Documentation
Form schema
Describe a form's fields once and everything else follows from that one list: validation of submissions, types for your code, an API description and the markup AI agents read. They can never drift apart, because they are all generated from the same schema. On every plan.
Last updated
Defining fields
Open the form's Settings, Fields and schema. If the form already has submissions, click Start from those and WebForms suggests the fields and types it has seen. For each field set a type (text, textarea, email, tel, url, number, date, select, radio, checkbox), whether it is required, the options for a select, and a sentence saying what it is for. That sentence is what AI agents read.
Validation
Tick Reject submissions that don't match and a submission with a missing required field, an invalid email or an unknown option gets a 422 listing each problem, before anything is stored or sent. It is off by default, so saving a schema never breaks a live form. Keep fields that aren't listed here decides whether extra fields are kept or refused.
Generated code
Below the editor: an agent-ready HTML form, TypeScript types, a Zod schema and JSON Schema, each with a copy button. The Zod schema runs the same checks WebForms runs on arrival, so validating in your own code first catches the same mistakes.
export type ContactSubmission = {
name: string;
/** Where we reply */
email: string;
plan?: "Starter" | "Team";
};Every form also has a public schema.json and openapi.json at its endpoint, e.g. https://send.webforms.to/your-key/openapi.json, always current, for tools and agents that read API descriptions.
Over the API and MCP
GET /v1/forms/:id/schema returns the fields and every generated output; PUT replaces the fields. Over MCP, an assistant can use get_form_schema and save_form_schema.
curl -X PUT https://api.webforms.to/v1/forms/frm_xxx/schema \
-H "Authorization: Bearer wf_live_your_key" \
-H "Content-Type: application/json" \
-d '{"fields": [
{"name": "name", "type": "text", "required": true},
{"name": "email", "type": "email", "required": true, "description": "Where we reply"},
{"name": "plan", "type": "select", "options": ["Starter", "Team"]}
], "enforceSchema": true}'Get your endpoint
Free for 300 submissions a month. No card required.
Start free