chatformdocs
Blocks

Field group

A small form asked once per person or item, repeated as many times as needed — two to five team members each with a name and an email, guests on a booking, line items on an order. Use this whenever the request describes the SAME set of details collected several times over; never a numbered run of separate questions ("Member 1 name", "Member 2 name"), which cannot stretch to a team of six or shrink to a team of two.

Advancedfield_group

A small form asked once per person or item, repeated as many times as needed — two to five team members each with a name and an email, guests on a booking, line items on an order. Use this whenever the request describes the SAME set of details collected several times over; never a numbered run of separate questions ("Member 1 name", "Member 2 name"), which cannot stretch to a team of six or shrink to a team of two.

How it gets answered — extracted from free text by the agent, then re-validated.

Configuration

Fields specific to field_group. The fields every block hasid, ref, title, required, visibility, media, agentHints, prefillParam, identityField — are documented once.

field_group configuration
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "buttonLabel": {
      "type": "string",
      "maxLength": 60
    },
    "type": {
      "type": "string",
      "const": "field_group"
    },
    "fields": {
      "minItems": 1,
      "maxItems": 10,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 6,
            "maxLength": 32
          },
          "key": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9_]{0,30}$"
          },
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "kind": {
            "type": "string",
            "enum": [
              "short_text",
              "long_text",
              "email",
              "phone",
              "url",
              "number",
              "date",
              "single_select",
              "yes_no"
            ]
          },
          "required": {
            "default": false,
            "type": "boolean"
          },
          "placeholder": {
            "type": "string",
            "maxLength": 200
          },
          "options": {
            "default": [],
            "maxItems": 50,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "minLength": 6,
                  "maxLength": 32
                },
                "label": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 500
                },
                "description": {
                  "type": "string",
                  "maxLength": 1000
                },
                "image_key": {
                  "default": null,
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "score": {
                  "type": "number"
                }
              },
              "required": [
                "id",
                "label"
              ]
            }
          },
          "min": {
            "type": "number"
          },
          "max": {
            "type": "number"
          }
        },
        "required": [
          "id",
          "key",
          "label",
          "kind"
        ]
      }
    },
    "itemLabel": {
      "default": "Entry",
      "type": "string",
      "minLength": 1,
      "maxLength": 60
    },
    "minEntries": {
      "default": 1,
      "type": "integer",
      "minimum": 1,
      "maximum": 20
    },
    "maxEntries": {
      "default": 5,
      "type": "integer",
      "minimum": 1,
      "maximum": 20
    }
  },
  "required": [
    "id",
    "ref",
    "title",
    "type",
    "fields"
  ],
  "$defs": {
    "__schema0": {
      "type": "object",
      "properties": {
        "op": {
          "type": "string",
          "enum": [
            "and",
            "or"
          ]
        },
        "conditions": {
          "default": [],
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "left": {
                "oneOf": [
                  {
                    "type": "object",
                    "properties": {
                      "kind": {
                        "type": "string",
                        "const": "ref"
                      },
                      "ref": {
                        "type": "string",
                        "pattern": "^[a-z][a-z0-9_]{1,40}$"
                      }
                    },
                    "required": [
                      "kind",
                      "ref"
                    ]
                  },
                  {
                    "type": "object",
                    "properties": {
                      "kind": {
                        "type": "string",
                        "const": "variable"
                      },
                      "name": {
                        "type": "string",
                        "pattern": "^[a-z][a-z0-9_]{0,40}$"
                      }
                    },
                    "required": [
                      "kind",
                      "name"
                    ]
                  },
                  {
                    "type": "object",
                    "properties": {
                      "kind": {
                        "type": "string",
                        "const": "hidden"
                      },
                      "name": {
                        "type": "string",
                        "pattern": "^[a-zA-Z_][a-zA-Z0-9_.-]{0,60}$"
                      }
                    },
                    "required": [
                      "kind",
                      "name"
                    ]
                  },
                  {
                    "type": "object",
                    "properties": {
                      "kind": {
                        "type": "string",
                        "const": "literal"
                      }
                    },
                    "required": [
                      "kind"
                    ]
                  }
                ]
              },
              "op": {
                "type": "string",
                "enum": [
                  "eq",
                  "neq",
                  "gt",
                  "gte",
                  "lt",
                  "lte",
                  "contains",
                  "not_contains",
                  "starts_with",
                  "ends_with",
                  "matches_regex",
                  "is_empty",
                  "is_not_empty",
                  "is_checked",
                  "is_not_checked",
                  "includes",
                  "not_includes",
                  "ranked_above",
                  "ranked_below"
                ]
              },
              "value": {
                "anyOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "number"
                  },
                  {
                    "type": "boolean"
                  },
                  {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                ]
              }
            },
            "required": [
              "left",
              "op"
            ]
          }
        },
        "groups": {
          "default": [],
          "type": "array",
          "items": {
            "$ref": "#/$defs/__schema0"
          }
        }
      },
      "required": [
        "op"
      ]
    }
  }
}

In a generated draft these arrive as config pairs: fields=<Label:kind|Label:kind> where kind is one of short_text, long_text, email, phone, url, number, date, single_select, yes_no — append * to make a field required, and list a select's choices in brackets (Role:single_select[Lead|Member]); item=<Team member> names one entry; min=<2>, max=<5> bound how many there may be.

What you receive

GET /v1/forms/{id} and every "next question" projects blocks through toPublicBlock. For the example above:

PublicBlock
{
  "id": "blk_group001",
  "ref": "q_team",
  "type": "field_group",
  "title": "Who is on your team?",
  "required": true,
  "imageKey": null,
  "media": null,
  "groupFields": [
    {
      "key": "name",
      "label": "Full name",
      "kind": "short_text",
      "required": true
    },
    {
      "key": "email",
      "label": "Email",
      "kind": "email",
      "required": true
    },
    {
      "key": "year",
      "label": "Year of study",
      "kind": "number",
      "required": false
    }
  ],
  "itemLabel": "Team member",
  "minEntries": 2,
  "maxEntries": 4
}

What you send

One object per entry, keyed by each field's key. Every value is checked by the rules of that field's own kind, so a column can also fail with any code that kind emits — an email column with invalid_email, a bounded number column with too_small. The hint names the entry and the column.

type Answer = Record<string, string | number | boolean>[];
curl -X POST https://api.chatform.in/v1/responses/{RESPONSE_ID}/answers \
  -H "x-api-key: $CHATFORM_SECRET_KEY" \
  -H "content-type: application/json" \
  -d '{"ref": "q_team", "value": [{"name":"  Maya Iyer ","email":"Maya@Northwind.CO"},{"name":"Rahul Nair","email":"rahul@northwind.co","year":"3"}]}'

What gets stored

The value is normalised before it is saved, so what you read back is not always what you sent.

You sendStored
[{"name":" Maya Iyer ","email":"Maya@Northwind.CO"},{"name":"Rahul Nair","email":"rahul@northwind.co","year":"3"}][{"name":"Maya Iyer","email":"maya@northwind.co"},{"name":"Rahul Nair","email":"rahul@northwind.co","year":3}]each field is canonicalized by the validator for its own kind — the same trimming, lowercasing and coercion it would get as a question of its own

Errors

CodeWhenMessage
required[{"name":"Maya Iyer"},{"name":"Rahul Nair","email":"rahul@northwind.co"}] — a required field, missing in one entry — the hint names whichTeam member 1 · Email is missing.
type{"name":"Maya Iyer"} — a single entry is still an array of onePlease fill in the team member details.
too_few[{"name":"Maya Iyer","email":"maya@northwind.co"}] — this block asks for at least twoPlease give at least 2 team members.
too_many[{"name":"A","email":"a@x.co"},{"name":"B","email":"b@x.co"},{"name":"C","email":"c@x.co"},{"name":"D","email":"d@x.co"},{"name":"E","email":"e@x.co"}]You can add up to 4 team members.
incomplete
too_long
invalid_email[{"name":"Maya Iyer","email":"nope"},{"name":"Rahul Nair","email":"rahul@northwind.co"}]Team member 1 · Email — that doesn't look like a valid email address.

On this page