Forms

Create a form

forms_create · Changes data · Markdown

Creates a form or survey with its own public page that anyone can open and answer.

$0.01 a call

From your agent’s balance. A call that fails costs nothing.

An example

Make a sign-up form for our ride club: name, email, their bike, how they ride, miles a week, and agreeing to the club rules. Add riders to the CRM.

Your agent callsforms_create$0.01 a call

The example business is Halverson Cycle & Repair, a bike shop with a repair workshop in Portland, Oregon. The reply is the one the tool really gives.

With these arguments
{
  "title": "Join the ride club",
  "description": "10% off service, and a group ride from the shop every Saturday morning.",
  "save_to_crm": true,
  "fields": [
    {
      "id": "full_name",
      "type": "short_text",
      "label": "Your name",
      "required": true
    },
    {
      "id": "email",
      "type": "email",
      "label": "Email",
      "required": true
    },
    {
      "id": "bike",
      "type": "short_text",
      "label": "Your bike",
      "required": true
    },
    {
      "id": "riding",
      "type": "choice",
      "label": "How do you ride?",
      "options": [
        "Commuting",
        "Gravel",
        "Road",
        "A bit of everything"
      ]
    },
    {
      "id": "miles",
      "type": "number",
      "label": "Miles a week",
      "min": 0,
      "integer": true
    },
    {
      "id": "rules",
      "type": "consent",
      "required": true,
      "label": "I agree to the [club rules](https://halversoncycle.example/ride-club)"
    }
  ]
}
What comes back
{
  "form": {
    "form_id": "d06fb065-da83-4a05-8154-0c92b4d74ccb",
    "slug": "join-the-ride-club",
    "url": "https://cncto.co/f/join-the-ride-club",
    "title": "Join the ride club",
    "status": "open",
    "accepting_responses": true,
    "closed_reason": null,
    "responses": 0,
    "last_response_at": null,
    "created_at": "2026-10-14T08:00:00+00:00",
    "description": "10% off service, and a group ride from the shop every Saturday morning.",
    "fields": [
      {
        "id": "full_name",
        "type": "short_text",
        "label": "Your name",
        "help": "",
        "required": true,
        "placeholder": "",
        "show_if": null
      },
      {
        "id": "email",
        "type": "email",
        "label": "Email",
        "help": "",
        "required": true,
        "placeholder": "",
        "show_if": null
      }
    ],
    "removed_fields": [],
    "submit_label": "Submit",
    "thank_you": {
      "title": "Thank you!",
      "message": "Your response was sent.",
      "redirect_url": null
    },
    "close_at": null,
    "max_responses": null,
    "notify_email": null,
    "save_to_crm": true,
    "confirm_to_respondent": false,
    "on_response": [],
    "hidden_fields": [],
    "updated_at": "2026-10-14T08:00:00+00:00"
  }
}

Use it when

The business wants to collect answers from people: requests, applications, feedback, sign-ups.

What it does

Create a form or survey with its own public page at https://cncto.co/f/<slug>, which anyone can open and answer; share that link. Field types: short_text, long_text, email, phone (default_country), url, number (min, max, integer), choice and multi_choice (options; multi_choice also min_selections, max_selections), rating (scale 3 to 10, default 5; low_label, high_label), nps (0 to 10; low_label, high_label), date (include_time for a time too, range for a first and a last day, earliest and latest as "2026-11-01" or "today", "today+7", "today-30"; answers read 2026-11-03, 2026-11-03T09:30, 2026-11-03/2026-11-07), yes_no, consent (a checkbox; its label may hold one link written [text](https://...)), statement (text only, no answer). Every field takes type, label, help, required, an id (generated from the label when left out; answers are keyed by it) and show_if {"field": "<an earlier field's id>", "equals": <answer>} to show it only when that answer was given. Each response received costs $0.01, up to 10,000 a month per account.

What comes back

The form with its form_id, slug, public url, status, whether it takes responses, its fields and settings, and notes when something needs a look. Every reply also carries cost_usd and balance_usd.

Inputs

NameTypeWhat it is
titleRequiredstring1 to 200 characters.
fieldsRequiredarray of objectsThe questions in order. When changing a form, this replaces the whole list. 1 to 100 items.
fields[].idstringStable id; answers are keyed by it. Generated from the label when left out. Pass it back when you change the form, or a renamed field becomes a new one. Matches ^[a-z0-9_]{1,40}$.
fields[].typeRequiredstringOne of: short_text,long_text,email,phone,url,number,choice,multi_choice,rating,nps,date,yes_no,consent,statement.
fields[].labelstringThe question. A statement's label is the text it shows. A consent label may hold one link: "I agree to the [terms](https://acme.com/terms)". Up to 1,000 characters.
fields[].helpstringSmaller text under the question. Up to 2,000 characters.
fields[].include_timebooleandate: a time too (answers like 2026-11-03T09:30).
fields[].rangebooleandate: a first and a last day (2026-11-03/2026-11-07).
fields[].earlieststring or nulldate: the first day that can be picked: "2026-11-01", "today", "today+1". Up to 20 characters.
fields[].lateststring or nulldate: the last day that can be picked: "2026-12-31", "today+60", "today". Up to 20 characters.
fields[].requiredbooleanDefault: false.
fields[].placeholderstringshort_text, long_text, email, phone, url and number only. Up to 200 characters.
fields[].default_countrystring or nullphone: the country of numbers typed without a +, like "US". Exactly 2 characters.
fields[].minnumber or nullnumber: the smallest answer.
fields[].maxnumber or nullnumber: the largest answer.
fields[].integerbooleannumber: whole numbers only.
fields[].optionsarray of string or objectchoice and multi_choice: ["Basic", "Pro"], or [{"id": "basic", "label": "Basic"}] to keep ids stable when you rename an option. 1 to 100 items.
fields[].min_selectionsinteger or nullmulti_choice: the fewest options. At least 1.
fields[].max_selectionsinteger or nullmulti_choice: the most options. At least 1.
fields[].scaleintegerrating: 3 to 10 (default 5). 3 to 10.
fields[].low_labelstringrating and nps: words under the lowest score. Up to 60 characters.
fields[].high_labelstringrating and nps: words under the top score. Up to 60 characters.
fields[].show_ifobject or nullShow this field only when an earlier field has this answer (for multi_choice: when that option is among the choices). A hidden field is never required.
fields[].show_if.fieldRequiredstringAn earlier field's id.
fields[].show_if.equalsRequiredanyThe answer that shows the field: an option id (choice, multi_choice), true or false (yes_no, consent), a number (number, rating, nps), a date (date) or text (short_text, email).
descriptionstringShown under the title. Up to 2,000 characters.
submit_labelstringThe button's words (default "Submit"). 1 to 40 characters.
thank_you_titlestringShown after sending (default "Thank you"). 1 to 120 characters.
thank_you_messagestringUp to 1,000 characters.
redirect_urlstring or nullAn https:// page to send people to after they submit. Empty or null: none. Up to 2,000 characters.
close_atstring or nullStop taking responses at this time (ISO 8601, like 2026-12-31T23:59:00Z; UTC when no offset is given). Empty or null: never. Up to 40 characters.
max_responsesinteger or nullStop after this many responses. 0 or null: no limit. 0 to 1,000,000.
notify_emailstring or nullEmail this address about new responses: at most one email a minute per form, later responses grouped into the next one. Free credit can only notify the owner's email. Empty or null: off. Up to 254 characters.
confirm_to_respondentbooleanEmail each respondent their answers in the brand kit (form_confirmation wording), to the address they typed in the first email field. $0.002 each; paid accounts only; at most three a day to one address.
on_responsearray of objectsWhat each response also does on its own, while you are away ($0.01 per action done): {"action": "open_ticket", "priority": "normal"} opens a help desk ticket for the respondent; {"action": "create_deal", "pipeline": "Sales", "stage": "New", "amount_field": "budget"} creates a deal with them as contact; {"action": "add_row", "table": "Leads", "columns": {"Email": "email", "Budget": "budget"}} adds a row, each column from a field id. [] or null: none. Up to 3 items.
on_response[].actionRequiredstringOne of: open_ticket,create_deal,add_row.
on_response[].prioritystringOne of: low,normal,high,urgent.
on_response[].pipelinestringUp to 80 characters.
on_response[].stagestringUp to 80 characters.
on_response[].amount_fieldstringUp to 40 characters.
on_response[].tablestringUp to 80 characters.
on_response[].columnsobject
save_to_crmbooleanSave the person behind each response as a CRM contact. The first email field is the email; a short_text field with id name or full_name (or first_name and last_name) is the name; the first phone field the phone. An existing contact only gets empty fields filled.
hidden_fieldsarray of stringsLink values kept with each response: ["ref", "utm_source"] keeps them from https://cncto.co/f/<slug>?ref=abc&utm_source=newsletter. Up to 10 items.

The call

Over MCP, call forms_create on https://api.conecto.chat/mcp/forms. Over REST:

Terminal
curl -X POST https://api.conecto.chat/v1/tools/forms_create \
  -H "Authorization: Bearer $CONECTO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"Join the ride club","description":"10% off service, and a group ride from the shop every Saturday morning.","save_to_crm":true,"fields":[{"id":"full_name","type":"short_text","label":"Your name","required":true},{"id":"email","type":"email","label":"Email","required":true},{"id":"bike","type":"short_text","label":"Your bike","required":true},{"id":"riding","type":"choice","label":"How do you ride?","options":["Commuting","Gravel","Road","A bit of everything"]},{"id":"miles","type":"number","label":"Miles a week","min":0,"integer":true},{"id":"rules","type":"consent","required":true,"label":"I agree to the [club rules](https://halversoncycle.example/ride-club)"}]}'

When it refuses

A refused call costs nothing and says what to do next.

CodeWhenWhat to do
invalid_input400A field or setting is not valid: a field type that does not take an option, a missing list of options, a show_if on a later field, a close_at in the past, or save_to_crm without an email field.Fix what the message names; it points at the field by its place, like fields[2].
payment_required_for_outbound402notify_email is not the owner's email, and the balance is still free credit.Notify the owner's email, or top up once (POST /v1/topups).
conflict409The form could not get its link just now.Call again.

Give this to your agent.

Set up Conecto from https://conecto.chat/SKILL.md