Forms and fields: the 11 field types and every setting

Updated 2026-10-30

A form is a title, an optional description, up to 50 fields and a few settings. Send it as JSON to POST /v1/forms. This page lists every field type and form setting. It lists the endpoints that manage forms. It lists the fields we refuse to store.

Create a form

bash
curl -X POST https://aiformapi.com/v1/forms \
  -H "Authorization: Bearer $AIFORMAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Customer feedback",
    "description": "Two minutes. We read every answer.",
    "fields": [
      {"id": "name", "label": "Your name", "type": "short_text"},
      {"id": "rating", "label": "How was it?", "type": "rating", "required": true}
    ],
    "settings": {"agent_fill": true}
  }'

201 returns id, slug, public_url, status (always open at first) and created_at.

The field object

PropertyTypeNotes
idstringRequired. snake_case: lower-case letters, digits and underscores, starting with a letter. Unique in the form, 40 characters or fewer. It is the key in answers and the column name in CSV.
labelstringRequired. The question the person sees. Up to 200 characters.
typestringRequired. One of the 11 types below.
requiredbooleanOptional. Default false.
helpstringOptional. A short hint under the question. Up to 500 characters.
optionsarray of stringsRequired for single_choice and multi_choice: 2 to 50 distinct options. Not allowed on other types.
min, maxnumberFor number: the smallest and largest value. For rating: the lowest and highest score (default 1 to 5, within 0 to 10). For multi_choice: the fewest and most choices.
max_lengthintegerFor short_text and long_text. Cannot be higher than the type limit.

A form needs at least 1 field and can hold at most 50. The title can be up to 200 characters and the description up to 2,000. Pick ids you will keep. If you rename an id later, the CSV column and the answer key change with it. The API rejects properties it does not know.

Field types

Each example shows the field and a valid answer.

short_text

One line, up to 500 characters.

json
{"id": "full_name", "label": "Your name", "type": "short_text", "required": true, "max_length": 80}

Answer: "Ada Lovelace"

long_text

Several lines, up to 5,000 characters.

json
{"id": "message", "label": "How can we help?", "type": "long_text", "max_length": 2000}

Answer: "I would like to change my booking to Friday."

email

json
{"id": "email", "label": "Email address", "type": "email", "required": true}

Answer: "ada@example.com"

number

json
{"id": "guests", "label": "How many guests?", "type": "number", "min": 0, "max": 5}

Answer: 2 (a JSON number, not a string)

url

json
{"id": "portfolio", "label": "Link to your work", "type": "url"}

Answer: "https://example.com/work"

phone

json
{"id": "mobile", "label": "Mobile number", "type": "phone", "help": "Include the country code."}

Answer: "+44 7700 900123"

single_choice

The person picks one option.

json
{"id": "meal", "label": "Main course", "type": "single_choice", "required": true,
 "options": ["Chicken", "Fish", "Vegetarian"]}

Answer: "Fish" (must match one option exactly)

multi_choice

The person picks any number of options.

json
{"id": "days", "label": "Which days can you work?", "type": "multi_choice",
 "options": ["Mon", "Tue", "Wed", "Thu", "Fri"]}

Answer: ["Mon", "Wed"]

checkbox

A single yes or no box. A required checkbox must be ticked.

json
{"id": "agree_to_rules", "label": "I read the house rules", "type": "checkbox", "required": true}

Answer: true

date

json
{"id": "start_date", "label": "Start date", "type": "date"}

Answer: "2026-11-15" (ISO format, YYYY-MM-DD)

rating

A whole number from min to max. The default range is 1 to 5. You can set a range anywhere from 0 to 10.

json
{"id": "satisfaction", "label": "How happy are you?", "type": "rating", "min": 1, "max": 10}

Answer: 8

How answers are checked

The same checks run for the form page, the paste box, POST /v1/fill/{token} and the fill MCP server.

  • An optional field can be left out. An empty string, null or an empty list also counts as skipped.
  • A required field must have a value. A required checkbox must be true.
  • Text is trimmed. A single_choice or multi_choice value must match an option. Letter case does not matter.
  • A number can arrive as a JSON number or as a numeric string. It is stored as a number.
  • A phone number needs 5 to 15 digits. A url must start with http:// or https://. A date must be a real calendar date.
  • An answer for a field id the form does not have is an error. Send only ids that exist in the form.

Each problem comes back as {"id": "field_id", "problem": "..."}. See Fill API.

Form settings

Send settings when you create a form or change it with PATCH.

SettingTypeWhat it does
agent_fillbooleanShows the "Want your AI agent to fill this?" card and allows fill tokens. Default true. Set it to false to turn agent fill off. See Agent fill.
close_atdate and timeThe form closes by itself at this time. Use an ISO 8601 value such as 2026-12-01T00:00:00Z. null clears it.
max_responsesintegerThe form closes to new answers after this many responses. null clears it.
confirmation_messagestringThe text a person sees after a successful submit. Up to 500 characters.
notify_emailbooleanSend the account owner an email for each new response. Default false.

Free plan: there is no redirect after submit. If you send a redirect setting, the API tells you it is not available. The person always sees the confirmation message. Forms cannot hold custom HTML or JavaScript.

Manage forms

All of these need your API key.

Method and pathWhat it does
GET /v1/forms?limit=&cursor=Lists your forms. Pages with a cursor: 20 per page by default, 100 at most.
GET /v1/forms/{id}Reads one form: fields, settings, status, response count, public link and its webhooks with the last delivery status.
PATCH /v1/forms/{id}Changes the title, description, fields or settings.
POST /v1/forms/{id}/closeStops new responses. The public page says the form is closed.
POST /v1/forms/{id}/reopenAccepts responses again.
DELETE /v1/forms/{id}Deletes the form and all its responses. This cannot be undone. It returns {"id": "...", "deleted": true}.

Examples:

bash
# List
curl "https://aiformapi.com/v1/forms?limit=20" -H "Authorization: Bearer $AIFORMAPI_KEY"

# Rename and change the confirmation text
curl -X PATCH https://aiformapi.com/v1/forms/FORM_ID \
  -H "Authorization: Bearer $AIFORMAPI_KEY" -H "Content-Type: application/json" \
  -d '{"title": "Customer feedback, November", "settings": {"confirmation_message": "Thank you."}}'

# Close, then reopen
curl -X POST https://aiformapi.com/v1/forms/FORM_ID/close  -H "Authorization: Bearer $AIFORMAPI_KEY"
curl -X POST https://aiformapi.com/v1/forms/FORM_ID/reopen -H "Authorization: Bearer $AIFORMAPI_KEY"

On the free plan you can keep 3 forms open at once. Close a form to free a slot. Closed forms keep their responses.

Blocked fields

We refuse to store forms that ask for secrets. A form is a link anyone can send, so a form that asks for a password looks the same as a phishing page. Instead of trying to guess intent, we block the words.

The API returns 422 blocked_field when a field id, label or help matches any of these, in English or German, in any letter case:

password, passwort, passcode, PIN, CVV, CVC, card number, credit card, Kreditkarte, IBAN, seed phrase, recovery phrase, private key, 2FA, one-time code, OTP, social security, SSN, passport, Reisepass, Personalausweis, national ID, Aadhaar, Steuer-ID, NIN.

The last 7 ban government identity numbers:

  • passport matches passport and passport number.
  • Reisepass matches the German passport, also as Reisepassnummer.
  • Personalausweis matches the German identity card, also as Personalausweisnummer.
  • national ID matches national ID, national identity number and national identification number.
  • Aadhaar matches the Indian identity number, also spelled Aadhar.
  • Steuer-ID matches Steuer-ID, Steueridentifikationsnummer and steuerliche Identifikationsnummer.
  • NIN matches the abbreviation NIN and the phrase National Insurance number.

Spaces, dashes and underscores do not matter, so card_number and card-number match too. Short codes such as PIN match as whole words only, so a field about shipping is fine. The word national identity on its own is allowed, but a field for a national identity number is not.

json
{
  "error": {
    "code": "blocked_field",
    "message": "Field \"account_pin\" asks for \"PIN\" (in its id). Forms cannot ask for passwords, codes, card or account numbers, and passport or national ID numbers.",
    "details": {
      "fields": [{"id": "account_pin", "where": "id", "matched": "PIN"}]
    }
  }
}

If your use case is legitimate, ask for the information another way. Collect a contact address and follow up in a tool that is built for secrets. The rules are in Acceptable use.

Validation errors

A body that breaks the rules above gets 422 validation_failed. The most common causes are an id with capital letters or spaces, a duplicate id, a choice field without options, an unknown property and more than 50 fields. The list of problems is in error.details.errors, each with a path and a message.

json
{
  "error": {
    "code": "validation_failed",
    "message": "fields[1].options: single_choice needs at least 2 options.",
    "details": {
      "errors": [{"path": "fields[1].options", "message": "single_choice needs at least 2 options."}]
    }
  }
}

Each error code is explained in Errors.

Next