Forms and fields: the 11 field types and every setting
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
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
| Property | Type | Notes |
|---|---|---|
id | string | Required. 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. |
label | string | Required. The question the person sees. Up to 200 characters. |
type | string | Required. One of the 11 types below. |
required | boolean | Optional. Default false. |
help | string | Optional. A short hint under the question. Up to 500 characters. |
options | array of strings | Required for single_choice and multi_choice: 2 to 50 distinct options. Not allowed on other types. |
min, max | number | For 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_length | integer | For 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.
{"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.
{"id": "message", "label": "How can we help?", "type": "long_text", "max_length": 2000}Answer: "I would like to change my booking to Friday."
email
{"id": "email", "label": "Email address", "type": "email", "required": true}Answer: "ada@example.com"
number
{"id": "guests", "label": "How many guests?", "type": "number", "min": 0, "max": 5}Answer: 2 (a JSON number, not a string)
url
{"id": "portfolio", "label": "Link to your work", "type": "url"}Answer: "https://example.com/work"
phone
{"id": "mobile", "label": "Mobile number", "type": "phone", "help": "Include the country code."}Answer: "+44 7700 900123"
single_choice
The person picks one option.
{"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.
{"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.
{"id": "agree_to_rules", "label": "I read the house rules", "type": "checkbox", "required": true}Answer: true
date
{"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.
{"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,
nullor an empty list also counts as skipped. - A required field must have a value. A required
checkboxmust betrue. - Text is trimmed. A
single_choiceormulti_choicevalue must match an option. Letter case does not matter. - A
numbercan arrive as a JSON number or as a numeric string. It is stored as a number. - A
phonenumber needs 5 to 15 digits. Aurlmust start withhttp://orhttps://. Adatemust 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.
| Setting | Type | What it does |
|---|---|---|
agent_fill | boolean | Shows 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_at | date and time | The form closes by itself at this time. Use an ISO 8601 value such as 2026-12-01T00:00:00Z. null clears it. |
max_responses | integer | The form closes to new answers after this many responses. null clears it. |
confirmation_message | string | The text a person sees after a successful submit. Up to 500 characters. |
notify_email | boolean | Send 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 path | What 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}/close | Stops new responses. The public page says the form is closed. |
POST /v1/forms/{id}/reopen | Accepts responses again. |
DELETE /v1/forms/{id} | Deletes the form and all its responses. This cannot be undone. It returns {"id": "...", "deleted": true}. |
Examples:
# 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:
passportmatches passport and passport number.Reisepassmatches the German passport, also asReisepassnummer.Personalausweismatches the German identity card, also asPersonalausweisnummer.national IDmatches national ID, national identity number and national identification number.Aadhaarmatches the Indian identity number, also spelled Aadhar.Steuer-IDmatches Steuer-ID, Steueridentifikationsnummer and steuerliche Identifikationsnummer.NINmatches 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.
{
"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.
{
"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
- Read answers back: Responses.
- Start from a ready-made definition: form templates.