Form schema
A OneForm form is a JSON definition: its questions, logic and screens. This is the JSON Schema (draft 2020-12) OneForm checks every save against, generated from the same code.
Structure
fields | The questions, in order: each with a unique id, a type, a title and required. |
welcome | The first screen, if any. |
thankYou | The default thank-you screen. |
endings | Other thank-you screens, chosen by conditions. |
variables | Numbers and text that logic can change, for scores. |
hiddenFields | Values the form takes from its link or embed: [{ key, label }]. |
settings | Languages and other form settings. |
translations | Text in other languages. |
report | The document OneFormAI writes from each submission: { enabled, title, prompt, docType }. |
Questions can carry visibleIf conditions and jumps; operators are is, is_not, contains, not_contains, any_of, none_of, all_of, eq, neq, gt, gte, lt, lte, before, after, answered, not_answered. A role (first_name, last_name, full_name, email, phone, company) tells OneForm who the respondent is, for names in reports and emails and for Leads.
Question types
| type | Shown as | Collects |
|---|---|---|
short_text | Short text | One line of text. |
long_text | Long text | A paragraph. |
multiple_choice | Multiple choice | One or several of choices: [{ id, label }]. multiple allows several, allowOther adds an Other box. |
yes_no | Yes / No | Yes or no. |
email | An email address. | |
phone | Phone number | A phone number. |
number | Number | A number. |
date | Date | A date. |
contact_group | Contact info | Several contact details on one screen, in fields of type short_text, email, phone, number. |
line_items | Line items | Rows of items, such as receipts or expenses. |
statement | Statement | Text to read. Asks nothing. |
The schema
Open a property to see what it holds. Required properties are marked.
welcomeobjectenabledbooleandefault truetitlestringrequireddescriptionstringlayoutstring"classic""card""image-top""banner""background""background-dark""split-left""split-right""side-third""avatar"imageobjecturlstringrequiredaltstring
overlaynumber≥ 0≤ 0.9showLogobooleanlinksobject[]at most 10kindstringrequired"website""linkedin""x""facebook""instagram""youtube""tiktok""email""phone""booking"urlstringrequiredmax length 2000labelstring
buttonTextstringdefault "Start"imageUrlstringbadgestringheadlinestring
fieldsobject[]requiredidstringrequiredmin length 1titlestringrequireddescriptionstringrequiredbooleandefault falseplaceholderstringrolestring"first_name""last_name""full_name""email""phone""company"typestringrequired"short_text""long_text""multiple_choice""yes_no""email""phone""number""date""contact_group""line_items""statement"choicesobject[]idstringrequiredmin length 1labelstringrequired
allowOtherbooleanmultiplebooleanfieldsobject[]idstringrequiredmin length 1titlestringrequireddescriptionstringrequiredbooleandefault falseplaceholderstringrolestring"first_name""last_name""full_name""email""phone""company"typestringrequired"short_text""email""phone""number"
mediaobjectkindstringrequired"image""video"urlstringrequiredaltstringlayoutstring"stack""split-left""split-right"
buttonTextstringvisibleIfobjectmatchstringrequired"all""any"conditionsobject[]requiredidstringrequiredleftobject | object | objectrequiredopstringrequired"is""is_not""contains""not_contains""any_of""none_of""all_of""eq""neq""gt""gte""lt""lte""before""after""answered""not_answered"valuestring | number | boolean | string[]
jumpsobject[]idstringrequiredwhenobjectrequiredmatchstringrequired"all""any"conditionsobject[]requiredidstringrequiredleftobject | object | objectrequiredopstringrequired"is""is_not""contains""not_contains""any_of""none_of""all_of""eq""neq""gt""gte""lt""lte""before""after""answered""not_answered"valuestring | number | boolean | string[]
gotoobject | objectrequired
otherwiseobject | objectcalcobject[]idstringrequiredvarstringrequiredopstringrequired"add""subtract""multiply""set""add_answer"amountnumberrequiredwhenobjectmatchstringrequired"all""any"conditionsobject[]requiredidstringrequiredleftobject | object | objectrequiredopstringrequired"is""is_not""contains""not_contains""any_of""none_of""all_of""eq""neq""gt""gte""lt""lte""before""after""answered""not_answered"valuestring | number | boolean | string[]
leadPoints{ [key]: number }lineItemsobjectcurrencystringshowDatebooleanshowCategorybooleanshowQuantitybooleancategoriesstring[]taxRatenumbermaxRowsinteger≥ -9007199254740991≤ 9007199254740991
pinstring"first""last"
thankYouobjectrequiredidstringtitlestringrequireddescriptionstringlayoutstring"classic""card""image-top""banner""background""background-dark""split-left""split-right""side-third""avatar"imageobjecturlstringrequiredaltstring
overlaynumber≥ 0≤ 0.9showLogobooleanlinksobject[]at most 10kindstringrequired"website""linkedin""x""facebook""instagram""youtube""tiktok""email""phone""booking"urlstringrequiredmax length 2000labelstring
ctaobjecttextstringrequiredurlstringrequiredmax length 2000
redirectobjecturlstringrequireddelaySecnumber≥ 0≤ 30paramsstring[]
whenobjectmatchstringrequired"all""any"conditionsobject[]requiredidstringrequiredleftobject | object | objectrequiredopstringrequired"is""is_not""contains""not_contains""any_of""none_of""all_of""eq""neq""gt""gte""lt""lte""before""after""answered""not_answered"valuestring | number | boolean | string[]
hideOfferbooleanschedulerobjectproviderstringrequired"calendly""calcom""tidycal""acuity""savvycal""youcanbookme""hubspot""zoho""msbookings""google""other""oneform"urlstringmax length 500displaystring"inline""button"heightinteger≥ 400≤ 1600prefillbooleanlabelstringmax length 60
endingsobject[]idstringrequiredtitlestringrequireddescriptionstringlayoutstring"classic""card""image-top""banner""background""background-dark""split-left""split-right""side-third""avatar"imageobjecturlstringrequiredaltstring
overlaynumber≥ 0≤ 0.9showLogobooleanlinksobject[]at most 10kindstringrequired"website""linkedin""x""facebook""instagram""youtube""tiktok""email""phone""booking"urlstringrequiredmax length 2000labelstring
ctaobjecttextstringrequiredurlstringrequiredmax length 2000
redirectobjecturlstringrequireddelaySecnumber≥ 0≤ 30paramsstring[]
whenobjectmatchstringrequired"all""any"conditionsobject[]requiredidstringrequiredleftobject | object | objectrequiredopstringrequired"is""is_not""contains""not_contains""any_of""none_of""all_of""eq""neq""gt""gte""lt""lte""before""after""answered""not_answered"valuestring | number | boolean | string[]
hideOfferbooleanschedulerobjectproviderstringrequired"calendly""calcom""tidycal""acuity""savvycal""youcanbookme""hubspot""zoho""msbookings""google""other""oneform"urlstringmax length 500displaystring"inline""button"heightinteger≥ 400≤ 1600prefillbooleanlabelstringmax length 60
variablesobject[]namestringrequiredlabelstringinitialnumber
hiddenFieldsobject[]keystringrequiredlabelstring
settingsobjectshowQuestionNumbersbooleanlanguagesobjectenabledbooleanrequireddefaultstring"en""fr""es"availablestring[]autoDetectboolean
voiceobjectenabledbooleanrequiredmaxSecondsnumbermodestring"offer""native"voicestringfillManybooleangoalstringcolorsstring[]at most 3
personalizationobjectenabledbooleanrequired
consultationobjectenabledbooleanrequiredtitlestringmax length 120descriptionstringmax length 600durationMininteger≥ 5≤ 480priceobjectamountintegerrequired≥ 0≤ 1000000currencystringrequiredmin length 3max length 3
locationobjectkindstringrequired"zoom""meet""teams""phone""in_person""custom"phoneModestring"firm_calls""invitee_calls"phonestringmax length 40addressstringmax length 300urlstringmax length 500
bufferBeforeMininteger≥ 0≤ 240bufferAfterMininteger≥ 0≤ 240minNoticeMininteger≥ 0≤ 43200maxDaysAheadinteger≥ 1≤ 365maxPerDayinteger≥ 1≤ 50hours{ [key]: object[] }remindersbooleanchangeHoursinteger≥ 0≤ 720refundHoursinteger≥ 0≤ 720confirmationstringmax length 600
kindstring"booking"dynamicobjectenabledbooleanrequiredmaxQuestionsinteger≥ -9007199254740991≤ 9007199254740991minQuestionsinteger≥ -9007199254740991≤ 9007199254740991goalstring
translations{ [key]: { [key]: object } }reportobjectenabledbooleanrequiredtitlestringdefault "Your personalized report"promptstringdefault ""ideastringkindstring"report""document"docTypestring"report""onboarding""engagement_letter""proposal""invoice""bill""checklist""hr_record""tax_organizer""document_request""memo""scope""task_list"audiencestring"respondent""internal"useAibooleanpdfStylestring"classic""modern""executive""minimal"deliverystring"ai""file"fileobjectidstringrequirednamestringrequiredbytesintegerrequired≥ -9007199254740991≤ 9007199254740991
fileSummarystringmax length 600autoSendbooleanautoSendAckstringnextStepobjectkindstringrequired"none""booking""form"formIdstringlabelstringmax length 60
pricingobjectenabledbooleanrequiredamountintegerrequired≥ 0≤ 1000000currencystringrequiredmin length 3max length 3headlinestringmax length 120bulletsstring[]at most 5buttonLabelstringmax length 60
Example
A small, valid form: five questions, one shown only to business owners, and a report.
{ "welcome": { "enabled": true, "title": "Let's find your tax savings", "description": "Two minutes, five questions.", "buttonText": "Start" }, "fields": [ { "id": "name", "type": "short_text", "title": "What's your first name?", "required": true, "role": "first_name" }, { "id": "business", "type": "yes_no", "title": "Do you own a business?", "required": true }, { "id": "entity", "type": "multiple_choice", "title": "How is it set up?", "required": true, "choices": [ { "id": "sole", "label": "Sole proprietor" }, { "id": "llc", "label": "LLC" }, { "id": "scorp", "label": "S corporation" } ], "visibleIf": { "match": "all", "conditions": [ { "id": "c1", "left": { "kind": "field", "fieldId": "business" }, "op": "is", "value": true } ] } }, { "id": "income", "type": "number", "title": "Roughly what did you earn last year?", "required": false }, { "id": "contact", "type": "contact_group", "title": "Where should we send your report?", "required": true, "fields": [ { "id": "email", "type": "email", "title": "Email", "required": true, "role": "email" }, { "id": "phone", "type": "phone", "title": "Phone", "required": false, "role": "phone" } ] } ], "thankYou": { "title": "Thanks, {{first_name|there}}!", "description": "We'll email your report once a CPA has reviewed it." }, "report": { "enabled": true, "title": "Your tax opportunities", "prompt": "Write a short, friendly report of the tax-saving opportunities that fit these answers." }}Checking a definition
AI agents connected to OneForm's MCP server can read this schema with get_form_schema (or the oneform://docs/form-schema resource), check a draft with validate_form_definition, and then create it with create_form. New forms are drafts until someone publishes them.
In your own code, any JSON Schema 2020-12 validator can check a definition against form-schema.json. OneForm also checks what a schema can't: that uploaded files and booking links work, and logic rules that point nowhere or can never be true (warnings). That's what validate_form_definition reports.