Skip to content

Form Definition Reference

A form definition is the JSON that describes a form: its fields, steps, conditions, limits, and spam settings. The builder writes it for you, and the server enforces it on every submission. Use this page when you need the exact name or value of a setting.

Each example below is a definition patch. Every top-level key you send replaces that whole key, and keys you leave out stay as they are. To add one field, send every existing field plus the new one.

These top-level keys can be changed: fields, steps, contentBlocks, conditions, visibilityRules, validationRules, limits, spam, verification, settings, allowedOrigins, and primaryPublicTarget.

Recipients, senders, and notification emails aren’t part of this patch. Set them on the form’s Delivery and Templates tabs. See Getting Started.

Field Names And Paths

fields maps a field name to its definition. Names use letters, digits, _, and -.

Other settings refer to a field by its path:

PathRefers to
emailA top-level field
contact.emailA field inside the contact group
guests[]Every item of the guests list, in steps, content blocks, and visibility rules
guests[0].nameOne item of the list, in conditions and validation rules

A path that doesn’t exist fails with FORM_CONFIG_FIELD_REF_UNKNOWN.

Field Types

type takes one of these twelve values. Anything else, such as file or signature, fails with FORM_CONFIG_FIELD_TYPE_INVALID.

typeCollectsSubmitted as
stringShort textString
textareaLong textString
emailAn email address, always checked for formatString
urlA web address, always checked for formatString
phoneA phone numberString
numberA numberNumber, or a string that converts to one
booleanYes or notrue or false
dateA date as YYYY-MM-DD, always checkedString
selectOne choice from a listString
checkboxOne tick box, or several choicestrue or false, or a string or array of strings with allowedValues
objectA group of fieldsObject
arrayA repeating itemArray

Rating and slider questions in the builder are number fields. There are no file upload or signature fields.

Options For Every Field

OptionValueEffect
labelStringThe field’s name on the form
descriptionStringHelp text under the field
requiredtrue or falseAn empty answer fails with FIELD_REQUIRED
placeholderStringHint inside the field. Not on object or array
defaultValueDepends on typeStarting answer. Not on object or array
messagesObject of stringsYour own error text, keyed by rule or by error code
JSON
{
  "fields": {
    "name": {
      "type": "string",
      "label": "Your name",
      "description": "As it appears on your invoice.",
      "placeholder": "Jane Example",
      "required": true,
      "messages": { "required": "Enter your name." }
    }
  }
}

A defaultValue must match the field: a finite number on number, true or false on boolean, a real YYYY-MM-DD date on date, and a string on other text types. With allowedValues, it must be one of them.

Text Fields

These options work on string, textarea, email, url, phone, and on date and select where the table says so.

OptionValueWorks onError code
min, maxLength, 0 or moreAll text typesFIELD_STRING_TOO_SHORT, FIELD_STRING_TOO_LONG
exactLengthLength, 0 or more. Can’t combine with min or maxAll text types, date, selectFIELD_STRING_LENGTH_INVALID
pattern, flagsRegular expression up to 500 characters. flags takes i, m, and uAll text typesFIELD_PATTERN_INVALID
allowedValuesArray of stringsAll text typesFIELD_VALUE_NOT_ALLOWED
startsWith, endsWithNon-empty stringstring, textarea, email, url, phoneFIELD_STRING_PREFIX_INVALID, FIELD_STRING_SUFFIX_INVALID
contains, notContainsNon-empty stringstring, textarea, email, url, phoneFIELD_STRING_CONTAINS_REQUIRED, FIELD_STRING_CONTAINS_FORBIDDEN
JSON
{
  "fields": {
    "reference": {
      "type": "string",
      "label": "Reference",
      "min": 4,
      "max": 20,
      "startsWith": "REF-",
      "pattern": "^REF-[0-9]+$"
    },
    "message": {
      "type": "textarea",
      "label": "Message",
      "required": true,
      "max": 5000,
      "trim": true
    }
  }
}

Masked And Hidden Text

On string only, inputType is password or hidden. It changes how the field shows. Validation still treats it as a string.

JSON
{
  "fields": {
    "access_code": { "type": "string", "label": "Access code", "inputType": "password" },
    "campaign": { "type": "string", "inputType": "hidden", "defaultValue": "spring" }
  }
}

Format Checks On Text

These options work on string fields. countryCode and regionCodeCountry also work on select.

OptionValueError code
uuidVersionany, v4, or v7FIELD_UUID_INVALID
countryCodeiso2FIELD_COUNTRY_CODE_INVALID
postalCodeCountryCA or USFIELD_POSTAL_CODE_INVALID
regionCodeCountryCA or USFIELD_REGION_CODE_INVALID
timeFormatHH:mm or HH:mm:ssFIELD_TIME_INVALID
dateTimeFormatiso8601, which needs a time zoneFIELD_DATETIME_INVALID
JSON
{
  "fields": {
    "postal_code": { "type": "string", "label": "Postal code", "postalCodeCountry": "CA" },
    "province": { "type": "select", "label": "Province", "regionCodeCountry": "CA", "allowedValues": ["QC", "ON"] },
    "pickup_time": { "type": "string", "label": "Pickup time", "timeFormat": "HH:mm" }
  }
}

Email Fields

email answers are always checked for format, and fail with FIELD_EMAIL_INVALID. normalizeEmail lowercases the address before it’s checked and stored.

JSON
{
  "fields": {
    "email": { "type": "email", "label": "Email", "required": true, "max": 254, "trim": true, "normalizeEmail": true }
  }
}

URL Fields

url answers are always checked, and accept http and https by default. Use allowedProtocols to change that. javascript, data, and vbscript aren’t allowed. A bad address fails with FIELD_URL_INVALID, and another protocol with FIELD_URL_PROTOCOL_NOT_ALLOWED.

JSON
{
  "fields": {
    "website": { "type": "url", "label": "Website", "allowedProtocols": ["https"] }
  }
}

Phone Fields

A phone field accepts any text by default. phoneFormat takes e164, which requires a number such as +15145550123, and fails with FIELD_PHONE_INVALID.

JSON
{
  "fields": {
    "phone": { "type": "phone", "label": "Phone", "phoneFormat": "e164" }
  }
}

Number Fields

OptionValueError code
min, maxThe lowest and highest value, 0 or moreFIELD_NUMBER_TOO_SMALL, FIELD_NUMBER_TOO_LARGE
integertrue for whole numbers onlyFIELD_INTEGER_REQUIRED
maxDecimalPlacesWhole number, 0 or moreFIELD_DECIMAL_PLACES_INVALID

A value that can’t be read as a number fails with FIELD_TYPE_INVALID. min and max can’t be negative, on any field type.

JSON
{
  "fields": {
    "rating": { "type": "number", "label": "Your rating", "integer": true, "min": 1, "max": 5 },
    "budget": { "type": "number", "label": "Budget", "maxDecimalPlaces": 2 }
  }
}

Date Fields

date answers must be real calendar dates as YYYY-MM-DD. dateMin and dateMax take the same format, and include the date you give.

RuleError code
Not a real dateFIELD_DATE_INVALID
Before dateMinFIELD_DATE_TOO_EARLY
After dateMaxFIELD_DATE_TOO_LATE
JSON
{
  "fields": {
    "event_date": { "type": "date", "label": "Event date", "dateMin": "2027-01-01", "dateMax": "2027-12-31" }
  }
}

Choice Fields

Use select for one choice. List the choices in allowedValues.

JSON
{
  "fields": {
    "department": { "type": "select", "label": "Department", "required": true, "allowedValues": ["Sales", "Support"] }
  }
}

Several Choices

Use checkbox with allowedValues. minSelections and maxSelections set the range, and fail with FIELD_SELECTION_TOO_FEW and FIELD_SELECTION_TOO_MANY. defaultValue is a string or an array of strings from the list.

JSON
{
  "fields": {
    "interests": {
      "type": "checkbox",
      "label": "Interests",
      "allowedValues": ["Workshops", "Newsletter", "Events"],
      "minSelections": 1,
      "maxSelections": 2,
      "defaultValue": ["Newsletter"]
    }
  }
}

One Tick Box

Without allowedValues, a checkbox is one tick box, and boolean works the same way. defaultValue is true or false. Add accepted when the box must be ticked, such as for consent. It fails with FIELD_ACCEPTED_REQUIRED.

JSON
{
  "fields": {
    "consent": { "type": "checkbox", "label": "I agree to the terms", "required": true, "accepted": true },
    "subscribe": { "type": "boolean", "label": "Send me the newsletter", "defaultValue": false }
  }
}

Groups

type: "object" groups fields under a shared name. It takes label, description, required, messages, and fields. Groups can nest up to 8 levels. Answers arrive as an object, and their paths look like contact.email.

JSON
{
  "fields": {
    "contact": {
      "type": "object",
      "label": "Contact",
      "fields": {
        "name": { "type": "string", "label": "Name", "required": true },
        "email": { "type": "email", "label": "Email", "required": true }
      }
    }
  }
}

Lists

type: "array" repeats one item. item holds any field type, including a group.

OptionValueError code
minItemsWhole number, 0 or moreFIELD_ARRAY_TOO_SHORT
maxItemsWhole number, 0 or moreFIELD_ARRAY_TOO_LONG
uniqueItemstrue to refuse repeatsFIELD_ARRAY_DUPLICATES
JSON
{
  "fields": {
    "guests": {
      "type": "array",
      "label": "Guests",
      "minItems": 1,
      "maxItems": 5,
      "item": {
        "type": "object",
        "fields": {
          "name": { "type": "string", "label": "Guest name", "required": true }
        }
      }
    }
  }
}

Cleaning Answers

Processors clean an answer before it’s validated. The result is the value that’s stored and delivered. They work on string, textarea, email, url, phone, date, and select, and a field can have up to 25 of each.

sanitizers run first, then trim, collapseWhitespace, and normalizeEmail, then transformers, then caseTransform.

Sanitizer typeWhat it does
trimRemoves spaces at the start and end
collapseWhitespaceTurns any run of spaces and line breaks into one space
normalizeNewlinesMakes every line break the same
stripTagsRemoves anything written like an HTML tag
removeUrlsRemoves web addresses that start with http://, https://, or www.
removeEmojiRemoves emoji
digitsOnlyKeeps only digits. On string and phone only
Transformer typeAlso needsWhat it does
casemode: upper or lowerChanges the case of the whole answer
mapvalues: up to 100 stringsSwaps one whole answer for another. The answer must match exactly
JSON
{
  "fields": {
    "province": {
      "type": "string",
      "label": "Province",
      "sanitizers": [{ "type": "trim" }, { "type": "collapseWhitespace" }],
      "transformers": [{ "type": "case", "mode": "upper" }, { "type": "map", "values": { "QC": "Québec" } }]
    }
  }
}

Shortcut Options

OptionValueWorks on
trimtrueText fields
collapseWhitespacetruestring, textarea
normalizeEmailtrueemail
caseTransformupper or lowerstring, textarea, select

Pipelines

pipeline runs sanitizers, transformers, and validators in one list that you order yourself. It can’t be combined with sanitizers, transformers, validators, trim, collapseWhitespace, normalizeEmail, or caseTransform, fails with FORM_CONFIG_FIELD_OPTION_CONFLICT if you try, and needs at least one step. The app’s Processing tab shows a pipeline without letting you edit it, so prefer the two lists above.

JSON
{
  "fields": {
    "code": {
      "type": "string",
      "label": "Code",
      "pipeline": [
        { "step": "sanitizer", "sanitizer": { "type": "trim" } },
        { "step": "validator", "validator": { "type": "startsWith", "value": "A", "code": "CODE_PREFIX", "message": "Start the code with A." } },
        { "step": "transformer", "transformer": { "type": "case", "mode": "lower" } }
      ]
    }
  }
}

Validators

Add checks to a text field with validators. Each one needs a type, a code in capitals such as CUSTOM_POSTAL_CODE, and the message to show. Validation responses return your code and message.

typeAlso takesPasses when the answer is
emailAn email address
urlallowedProtocolsA web address
domainA domain name
phoneE164format: e164A number such as +15145550123
postalCodecountry: CA or US, requiredA postal or ZIP code
regionCodecountry: CA or US, requiredA province or state code
countryCodeformat: iso2A two-letter country code
uuidversion: any, v4, or v7A UUID
ipAn IPv4 or IPv6 address
ipv4An IPv4 address
ipv6An IPv6 address
containsvalue, requiredContains the text
notContainsvalue, requiredDoesn’t contain the text
startsWithvalue, requiredStarts with the text
endsWithvalue, requiredEnds with the text
regexpattern, required, up to 500 characters. flags: i, m, uMatches the expression
JSON
{
  "fields": {
    "postal_code": {
      "type": "string",
      "label": "Postal code",
      "validators": [
        { "type": "postalCode", "country": "CA", "code": "CUSTOM_POSTAL_CODE", "message": "Enter a valid postal code." }
      ]
    },
    "sku": {
      "type": "string",
      "label": "Product code",
      "validators": [
        { "type": "regex", "pattern": "^[A-Z]{3}-[0-9]{4}$", "code": "CUSTOM_SKU", "message": "Use a code such as ABC-1234." }
      ]
    }
  }
}

Conditions

A condition is true or false for a set of answers. It’s used by visibility rules, validation rules, steps, and content blocks.

OperatorvalueTrue when the answer
isFilledNoneIsn’t empty
isEmptyNoneIs empty
equalsAnyEquals the value
notEqualsAnyDoesn’t equal the value
inArrayIs in the array
notInArrayIsn’t in the array
greaterThanNumber or textIs greater
greaterThanOrEqualNumber or textIs greater or equal
lessThanNumber or textIs less
lessThanOrEqualNumber or textIs less or equal
matchesRegular expressionMatches the expression

Combine conditions with all, any, and not. A condition can nest up to 5 levels, and a group can hold up to 25 conditions. An empty group fails with FORM_CONFIG_CONDITION_REQUIRED.

The next example is complete. It shows details when type is Commercial and size is over 10, or when type isn’t filled in.

JSON
{
  "fields": {
    "type": { "type": "select", "label": "Type", "allowedValues": ["Personal", "Commercial"] },
    "size": { "type": "number", "label": "Team size" },
    "details": { "type": "textarea", "label": "Details" }
  },
  "visibilityRules": [
    {
      "id": "show-details",
      "path": "details",
      "default": "hidden",
      "state": "visible",
      "when": {
        "any": [
          { "all": [
            { "path": "type", "operator": "equals", "value": "Commercial" },
            { "path": "size", "operator": "greaterThan", "value": 10 }
          ] },
          { "not": { "path": "type", "operator": "isFilled" } }
        ]
      }
    }
  ]
}

Named Conditions

conditions stores up to 100 conditions by name, for reuse in the app. Each has an id, and optionally a label up to 200 characters, a description up to 2,000, and a when. A rule keeps its own copy of the logic, so a named condition doesn’t change how a form behaves.

JSON
{
  "fields": {
    "type": { "type": "select", "label": "Type", "allowedValues": ["Personal", "Commercial"] }
  },
  "conditions": [
    {
      "id": "is-commercial",
      "label": "Commercial project",
      "when": { "path": "type", "operator": "equals", "value": "Commercial" }
    }
  ]
}

Visibility Rules

A visibility rule shows or hides one field or group. When when is true, the field takes state. Otherwise it takes default, which is visible if you leave it out. A form can have up to 100 rules, with one rule per field.

The server applies these rules too. Answers to a hidden field are dropped, and its checks don’t run.

JSON
{
  "fields": {
    "meal": { "type": "select", "label": "Meal", "allowedValues": ["Standard", "Other"] },
    "meal_details": { "type": "string", "label": "Tell us more" }
  },
  "visibilityRules": [
    {
      "id": "show-meal-details",
      "path": "meal_details",
      "default": "hidden",
      "state": "visible",
      "when": { "path": "meal", "operator": "equals", "value": "Other" }
    }
  ]
}

Validation Rules

A validation rule checks a field only when a condition is true. then holds up to 25 actions, each with a path and a validator. A form can have up to 100 rules.

The validator is any type from Validators, or one of these:

typeAlso takesPasses when
requiredThe field isn’t empty
allOfvalidatorsEvery validator in the list passes
anyOfvalidatorsAt least one validator in the list passes

Each needs a code and a message. allOf and anyOf lists hold up to 25 validators, and can nest up to 3 levels.

JSON
{
  "fields": {
    "type": { "type": "select", "label": "Type", "allowedValues": ["Personal", "Commercial"] },
    "company": { "type": "string", "label": "Company" }
  },
  "validationRules": [
    {
      "id": "company-if-commercial",
      "when": { "path": "type", "operator": "equals", "value": "Commercial" },
      "then": [
        {
          "path": "company",
          "validator": { "type": "required", "code": "COMPANY_REQUIRED", "message": "Enter the company name." }
        }
      ]
    }
  ]
}

Steps

steps groups fields into pages. With two or more, hosted pages and script embeds show one at a time, with Next, Back, and a counter. A form can have up to 50 steps.

OptionValueEffect
idUnique stringNames the step, including for step validation
fields1 to 100 pathsThe fields in this step. List conditional ones too
labelStringThe step’s title
summaryString up to 2,000 charactersShown under the title
validateOnstepSubmit, change, or blurchange lets Next skip the server check. The others check first
visibleWhenConditionHides the step and skips its fields unless this is true

Submitting always checks the whole form. See Sections And Multi-Step Forms.

JSON
{
  "fields": {
    "name": { "type": "string", "label": "Name", "required": true },
    "email": { "type": "email", "label": "Email", "required": true },
    "attending": { "type": "boolean", "label": "Will you attend?" },
    "meal": { "type": "select", "label": "Meal", "allowedValues": ["Standard", "Vegetarian"] }
  },
  "steps": [
    { "id": "about", "label": "About you", "summary": "How to reach you.", "fields": ["name", "email", "attending"], "validateOn": "stepSubmit" },
    {
      "id": "seat",
      "label": "Your seat",
      "fields": ["meal"],
      "visibleWhen": { "path": "attending", "operator": "equals", "value": true }
    }
  ]
}

Content Blocks

A content block puts text or a divider among the fields. It holds no answer, so it never reaches validation, submissions, or email. A form can have up to 100.

OptionValueEffect
idUnique stringNames the block
typetext or separatorA separator shows a line, with title as its label if set
titleString up to 200 charactersA heading
description, bodyStrings up to 5,000 charactersParagraphs, on text
before, afterField pathWhere it goes. Use one of them. With neither, it ends the form
visibleWhenConditionShows the block only when this is true
JSON
{
  "fields": {
    "name": { "type": "string", "label": "Name" },
    "seats": { "type": "number", "label": "Seats", "integer": true, "min": 1 }
  },
  "contentBlocks": [
    { "id": "intro", "type": "text", "title": "Seats are limited", "body": "Register early to save your spot.", "before": "name" },
    { "id": "divider", "type": "separator", "after": "name" },
    {
      "id": "group-note",
      "type": "text",
      "body": "We'll contact you about group rates.",
      "after": "seats",
      "visibleWhen": { "path": "seats", "operator": "greaterThan", "value": 5 }
    }
  ]
}

Limits

limits takes duplicateWindowSeconds, rateLimits, and quotas. Any other key fails the whole request with BAD_REQUEST. See Limits And Spam Protection for what each one does.

OptionValue
duplicateWindowSecondsWhole number. Anything under 60 acts as 60
rateLimits[].idUnique string
rateLimits[].scopeipHash per visitor, form, workspace, origin, deviceToken, or idempotencyKey
rateLimits[].windowSecondsWhole number, 1 or more
rateLimits[].maxWhole number, 1 or more
rateLimits[].messageYour own message
quotas[].idUnique string
quotas[].scopeform or workspace
quotas[].periodday, week, month, or lifetime
quotas[].maxAcceptedWhole number, 1 or more
quotas[].messageYour own message
JSON
{
  "limits": {
    "duplicateWindowSeconds": 300,
    "rateLimits": [
      { "id": "per-visitor", "scope": "ipHash", "windowSeconds": 600, "max": 10 },
      { "id": "whole-form", "scope": "form", "windowSeconds": 3600, "max": 300 }
    ],
    "quotas": [
      { "id": "cap", "scope": "form", "period": "lifetime", "maxAccepted": 200, "message": "Registration is full." }
    ]
  }
}

The response code stays RATE_LIMITED or FORM_QUOTA_REACHED whatever the message says.

Open and close dates aren’t part of limits. Set them under Response window on the Publish tab.

Spam Checks

OptionValueEffect
honeypotFieldField pathRejects a submission with this field filled. New forms use _formerie_hp. Leave it out to turn the check off
minSubmitTimeMsWhole number, 0 or moreRejects a form sent faster than this, when the client sends metadata.startedAt. 0 turns it off
maxLinksWhole number, 0 or moreRejects a submission with more links than this, across all its answers. 0 rejects any link. Leave it out to turn the check off
JSON
{
  "spam": {
    "honeypotField": "_formerie_hp",
    "minSubmitTimeMs": 1000,
    "maxLinks": 3
  }
}

Human Verification

OptionValueEffect
providerturnstile, recaptcha-v2, or recaptcha-v3The challenge to show
modemanaged or custommanaged uses Formerie’s keys, on turnstile only. Always set it
requiredtrue or falseWhether a submission must pass
siteKeyPublic site keyNeeded with custom when required is true
minScore0 to 1Lowest score to accept, on recaptcha-v3 only
expectedActionStringThe action the token must carry, on recaptcha-v3 only
JSON
{
  "verification": {
    "provider": "turnstile",
    "mode": "managed",
    "required": true
  }
}

With your own keys, enter the secret key in the app, under Human verification in the form’s Settings. It’s encrypted, and it stays in place when you change the rest of verification with the same provider. Until one is saved, required has to stay false, as in this example, or the change fails with FORM_CONFIG_VERIFICATION_SECRET_REQUIRED.

JSON
{
  "verification": {
    "provider": "recaptcha-v3",
    "mode": "custom",
    "required": false,
    "siteKey": "your-public-site-key",
    "minScore": 0.5,
    "expectedAction": "contact"
  }
}

Allowed Origins

allowedOrigins lists the sites whose browser code can call the form directly. Each entry is an exact origin with no path, and no wildcards. See Allowed Origins for when you need them.

JSON
{
  "allowedOrigins": ["https://www.example.com", "https://example.com", "http://localhost:5173"]
}

Public Address

primaryPublicTarget sets the address the form uses as its main one.

kindAlso needsAddress
workspaceThe workspace path on forms.formerie.com
formerieThe same Formerie address
runtimeHostnamehostname, and bindingKind: workspace or formYour own hostname. Connect it first under Domains
JSON
{
  "primaryPublicTarget": {
    "kind": "runtimeHostname",
    "hostname": "forms.example.com",
    "bindingKind": "workspace"
  }
}

Form Behaviour

settings.behavior holds what happens around the fields. settings replaces as a whole, so send behavior, branding, and layout together.

OptionValue
languageA language tag such as en-CA or fr-CA
submitButtonLabelUp to 80 characters
successMessageUp to 280 characters
successRedirectUrlAn http or https address, up to 500 characters

Branding

settings.branding styles the hosted page and script embed.

OptionValue
brandNameUp to 80 characters
logoUrlAn http or https address, up to 500 characters
densitycompact, comfortable, or spacious
fontPresetarial, georgia, helvetica, inter, mono, system, times, or verdana
previewThemelight or dark. Visitors get the one you choose
radiusnone, soft, or round
themes.light, themes.darkColours as #RRGGBB

Each theme takes accentColor, accentTextColor, backgroundColor, borderColor, errorColor, errorTextColor, fieldBackgroundColor, mutedTextColor, surfaceColor, and textColor.

Custom CSS isn’t applied to hosted pages.

Layout

settings.layout sets the width of the hosted page.

OptionValue
containerWidthModecontained, custom, or full
containerMinWidth, containerMaxWidthA length such as 44rem, 720px, 90%, or 72ch, with custom
JSON
{
  "settings": {
    "behavior": {
      "language": "fr-CA",
      "submitButtonLabel": "Envoyer",
      "successMessage": "Merci, nous vous répondrons sous peu."
    },
    "branding": {
      "brandName": "Example",
      "density": "comfortable",
      "fontPreset": "inter",
      "previewTheme": "light",
      "radius": "soft",
      "themes": { "light": { "accentColor": "#007c72" } }
    },
    "layout": { "containerWidthMode": "custom", "containerMaxWidth": "44rem" }
  }
}

Size Limits

WhatLimit
Fields on a form, counting those inside groups and lists250
Nesting of groups and lists8 levels
Steps50
Paths in a step100
Step summary2,000 characters
Content blocks100
Content block title200 characters
Content block description or body5,000 characters each
Named conditions100
Named condition label, description200, 2,000 characters
Visibility rules100
Validation rules100
Actions in a validation rule25
Conditions in a rule25
Condition nesting5 levels
Validators in an allOf or anyOf25, nested up to 3 levels
Sanitizers, transformers, or pipeline steps on a field25 of each
Entries in a map transformer100
Regular expression500 characters
A submission’s JSON body100,000 bytes

Reading Definition Errors

A rejected definition returns VALIDATION_FAILED with issues, and each issue has a path, a stable code, and a message. Fix those paths and send the patch again.

CodeWhat’s wrong
FORM_CONFIG_FIELD_TYPE_INVALIDtype isn’t one of the twelve field types
FORM_CONFIG_FIELD_OPTION_INVALIDThat option doesn’t work on this field type
FORM_CONFIG_FIELD_OPTION_CONFLICTTwo options can’t be used together
FORM_CONFIG_FIELD_REF_UNKNOWNA path names a field that doesn’t exist
FORM_CONFIG_FIELDS_REQUIREDThe form has no fields
FORM_CONFIG_NUMBER_TOO_SMALLA number is below its minimum
FORM_CONFIG_RANGE_INVALIDA minimum is above its maximum
FORM_CONFIG_DEFAULT_VALUE_INVALIDdefaultValue doesn’t suit the field
FORM_CONFIG_DEFAULT_VALUE_NOT_ALLOWEDdefaultValue isn’t in allowedValues
FORM_CONFIG_CODE_INVALIDA code isn’t in capitals, digits, and _
FORM_CONFIG_VALIDATOR_INVALIDThe validator type doesn’t exist
FORM_CONFIG_CONDITION_OPERATOR_INVALIDThe condition operator doesn’t exist
FORM_CONFIG_ID_DUPLICATETwo entries in a list share an id
FORM_CONFIG_ORIGIN_WILDCARDAn allowed origin uses *
FORM_CONFIG_ORIGIN_INVALIDAn allowed origin has a path, or isn’t http or https