/formsCreate Form
Create a new form with a complete schema
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
/formsHeaders
| Header | Value |
|---|---|
Authorization | Bearer fxk_live_<your-api-key> |
Content-Type | application/json |
Request Body
FormSchema Object
{
"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
| Type | Description |
|---|---|
text | Single-line text input |
textarea | Multi-line text input |
number | Numeric input |
email | Email address input |
select | Dropdown selection (requires options) |
radio | Radio button group (requires options) |
checkbox | Checkbox group (requires options) |
date | Date picker |
file | File upload (supports fileConfig) |
Field Options (for select, radio, checkbox)
{
"options": [
{ "label": "Option A", "value": "a" },
{ "label": "Option B", "value": "b" }
]
}
File Configuration (for file type)
{
"fileConfig": {
"maxSizeMB": 5,
"allowedTypes": ["image/*", "application/pdf"]
}
}
Validation Rules
Each field can have a validation object containing an array of rules:
{
"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 Type | Value | Description |
|---|---|---|
required | — | Field must have a value |
minLength | number | Minimum string length |
maxLength | number | Maximum string length |
min | number | Minimum numeric value |
max | number | Maximum numeric value |
pattern | string (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:
{
"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:
{
"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").
| Property | Type | Description |
|---|---|---|
action | string | show — display when conditions match, hide — hide when conditions match |
conditionGroups | array | Array of condition groups (OR'd together) |
conditionGroups[].conditions | array | Array of conditions within a group (AND'd together) |
conditions[].fieldId | string | ID of the field to evaluate |
conditions[].operator | string | Comparison operator (see table below) |
conditions[].value | string | number | boolean | Value to compare against (not required for some operators) |
Available Operators:
| Operator | Description | Requires value |
|---|---|---|
equals | Exact match | Yes |
notEquals | Not equal | Yes |
contains | String contains | Yes |
notContains | String does not contain | Yes |
startsWith | String starts with | Yes |
endsWith | String ends with | Yes |
greaterThan | Numeric greater than | Yes |
lessThan | Numeric less than | Yes |
greaterThanOrEqual | Numeric greater than or equal | Yes |
lessThanOrEqual | Numeric less than or equal | Yes |
before | Date before | Yes |
after | Date after | Yes |
isEmpty | Field has no value | No |
isNotEmpty | Field has a value | No |
isChecked | Checkbox is checked | No |
isNotChecked | Checkbox is not checked | No |
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.