POST/forms

Create Form

Create a new form with a complete schema

Scope: FORMS_WRITE

Overview

Creates a new form with the provided title and schema definition. The form is created in DRAFT status — use the Publish Form endpoint to make it available for submissions.

Request

POST/forms

Headers

HeaderValue
AuthorizationBearer fxk_live_<your-api-key>
Content-Typeapplication/json

Request Body

FormSchema Object

json
{
  "version": "1.0",
  "schemaVersion": "2026-02",
  "meta": {
    "title": "Form Title",
    "description": "Optional description",
    "language": "en",
    "submitLabel": "Submit"
  },
  "settings": {
    "layout": "single-column",
    "submitAction": "default"
  },
  "sections": [
    {
      "id": "section-1",
      "title": "Section Title",
      "order": 1
    }
  ],
  "fields": [
    {
      "id": "field-1",
      "sectionId": "section-1",
      "type": "text",
      "label": "Field Label",
      "order": 1,
      "required": true
    }
  ]
}

Supported Field Types

TypeDescription
textSingle-line text input
textareaMulti-line text input
numberNumeric input
emailEmail address input
selectDropdown selection (requires options)
radioRadio button group (requires options)
checkboxCheckbox group (requires options)
dateDate picker
fileFile upload (supports fileConfig)

Field Options (for select, radio, checkbox)

json
{
  "options": [
    { "label": "Option A", "value": "a" },
    { "label": "Option B", "value": "b" }
  ]
}

File Configuration (for file type)

json
{
  "fileConfig": {
    "maxSizeMB": 5,
    "allowedTypes": ["image/*", "application/pdf"]
  }
}

Validation Rules

Each field can have a validation object containing an array of rules:

json
{
  "validation": {
    "rules": [
      { "type": "required", "message": "This field is required" },
      { "type": "minLength", "value": 3, "message": "Minimum 3 characters" },
      { "type": "maxLength", "value": 500 },
      { "type": "min", "value": 0, "message": "Must be positive" },
      { "type": "max", "value": 100 },
      { "type": "pattern", "value": "^[A-Z]", "message": "Must start with uppercase" }
    ]
  }
}
Rule TypeValueDescription
requiredField must have a value
minLengthnumberMinimum string length
maxLengthnumberMaximum string length
minnumberMinimum numeric value
maxnumberMaximum numeric value
patternstring (regex)Value must match the regular expression

Each rule can include an optional message for custom error text, and an optional when condition to apply the rule only when another field meets a criteria:

json
{
  "type": "required",
  "message": "Required when rating is poor",
  "when": {
    "field": "field-rating",
    "equals": "poor"
  }
}

The when object supports equals and notEquals comparisons against another field's value.

Conditional Logic

Fields and sections can have conditional visibility rules. Conditions use an AND/OR group structure — conditions within a group are AND'd together, and groups are OR'd:

json
{
  "conditionalLogic": {
    "action": "show",
    "conditionGroups": [
      {
        "conditions": [
          {
            "fieldId": "field-rating",
            "operator": "equals",
            "value": "poor"
          },
          {
            "fieldId": "field-name",
            "operator": "isNotEmpty"
          }
        ]
      },
      {
        "conditions": [
          {
            "fieldId": "field-rating",
            "operator": "equals",
            "value": "average"
          }
        ]
      }
    ]
  }
}

This example means: show the field if (rating equals "poor" AND name is not empty) OR (rating equals "average").

PropertyTypeDescription
actionstringshow — display when conditions match, hide — hide when conditions match
conditionGroupsarrayArray of condition groups (OR'd together)
conditionGroups[].conditionsarrayArray of conditions within a group (AND'd together)
conditions[].fieldIdstringID of the field to evaluate
conditions[].operatorstringComparison operator (see table below)
conditions[].valuestring | number | booleanValue to compare against (not required for some operators)

Available Operators:

OperatorDescriptionRequires value
equalsExact matchYes
notEqualsNot equalYes
containsString containsYes
notContainsString does not containYes
startsWithString starts withYes
endsWithString ends withYes
greaterThanNumeric greater thanYes
lessThanNumeric less thanYes
greaterThanOrEqualNumeric greater than or equalYes
lessThanOrEqualNumeric less than or equalYes
beforeDate beforeYes
afterDate afterYes
isEmptyField has no valueNo
isNotEmptyField has a valueNo
isCheckedCheckbox is checkedNo
isNotCheckedCheckbox is not checkedNo

Example Request

curl -X POST "https://api.formfex.com/api/v1/public/forms" \
  -H "Authorization: Bearer $FORMFEX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Customer Feedback Survey",
    "schema": {
      "version": "1.0",
      "schemaVersion": "2026-02",
      "meta": { "title": "Customer Feedback Survey", "language": "en" },
      "sections": [{ "id": "s1", "title": "Feedback", "order": 1 }],
      "fields": [
        { "id": "f1", "sectionId": "s1", "type": "text", "label": "Name", "order": 1, "required": true },
        { "id": "f2", "sectionId": "s1", "type": "select", "label": "Rating", "order": 2,
          "options": [{ "label": "Good", "value": "good" }, { "label": "Poor", "value": "poor" }] }
      ]
    }
  }'

Response

Webhooks & Integrations

Creating a form triggers the FORM_CREATED webhook event. If you have Slack or Teams integrations configured, a notification is sent automatically.

Next Step

After creating a form, use the Publish Form endpoint to generate a share URL and start collecting responses.

n8n

In n8n, this operation is available as Create under the Form resource in the Formfex node.