The Form Builder block at the bottom of Form Details is where a form gets its fields. Add Field opens a menu of the twelve standard Leed fields, each of which can appear on a form once — a standard field already on the form is removed from the menu, which is why the list gets shorter as you build. Below them sits Custom Field, which adds a text field literally named my-super-cool-field for you to rename.
Standard fields
The standard fields are not a convenience list. Each one submits under a fixed name that Leed maps onto a real column on the contact record, so the same person filling any two of your forms is one contact rather than two — as long as both forms use the standard Email field rather than a custom field that happens to be called something like it.
| Display name | Submitted name | Type | Contact-record column |
|---|---|---|---|
| First Name | firstname | text | firstName |
| Last Name | lastname | text | lastName |
| Title | title | text | title |
email | email | email (plus a derived emailDomain) | |
| Phone | phone | tel | phone |
| Company | company | text | company |
| Address | address | text | address |
| City | city | text | city |
| State | state | text | state |
| Postal Code | postalcode | text | postalCode |
| Country | country | countries | country |
| Terms | terms | checkbox | terms |
Email carries extra weight: it is what decides whether a submission produces a contact at all, and Leed stores its domain separately so you can group by company later. A form with no Email field records submissions and creates nothing else.
Custom fields are captured too — they land in a JSON blob rather than a column, and show up in the submissions table alongside the standard ones.
The field row and its options
Each field is one row in the builder: its Name, its Input Type, a Required checkbox, a drag handle for reordering and a trash icon for removal. Reordering is what the visitor sees — the fields render in exactly this order. The chevron at the left of the row expands the editor for the rest of the options.
On a standard field, Name and Type are locked — changing either would break the mapping onto the contact record, so the builder does not let you. Multiple is grayed out for every type the builder can produce, and Rows is grayed out for everything except textarea.
| Option | Stored key | Required? | Applies to | What it emits |
|---|---|---|---|---|
| Required | required | — | every type | required="true" on the input |
| Name | name | yes | every type; locked on standard fields | the key the value is submitted under |
| Type | type | yes | every type; locked on standard fields | decides which element is rendered |
| Label Before | labelBefore | no | every type | a <label> before the input — HTML is allowed and is not escaped |
| Label After | labelAfter | no | every type | a <label> after the input — likewise unescaped |
| Placeholder | placeHolder | no | text, tel, email, checkbox, radio; on select and countries it becomes the empty leading option | placeholder="…" |
| Pattern | pattern | no | text, tel, email, checkbox, radio | pattern="…", enforced by the browser before submit |
| Value | value | no | every type | value="…"; a textarea’s initial content; a label’s text; the entire payload of a hidden field |
| Rows | rows | no | textarea only — grayed out elsewhere | rows="…" |
| Multiple | multiple | no | nothing the builder can select — grayed out everywhere | multiple="true" on a select |
| onChange | onchange | no | every type | an inline onchange="…" handler |
| onInput | oninput | no | text, tel, email, textarea, checkbox, radio | an inline oninput="…" handler |
Two more keys exist on a field and have no editor at all: options[] (the label/value pairs a select or radio group would need) and selected (which of them starts chosen). Both are marked TODO: handle in ui in the source, which is exactly why three field types below are unreachable.
Pattern is the option most worth reaching for. It is plain HTML5 validation, enforced in the browser before the submission is ever sent — [^@]+@yourcompany\.com on an Email field, or \d{10} on a Phone field, costs you nothing and removes a category of junk that Turnstile will not.
Field types
| Type | Selectable in the builder | Rendered element | Notes |
|---|---|---|---|
text | yes | <input type="text"> | the default for a custom field |
textarea | yes | <textarea> | the only type where Rows applies |
tel | yes | <input type="tel"> | |
email | yes | <input type="email"> | browser-validated as an address |
countries | yes | <select> | options come from the site builder’s ISO country list |
checkbox | only as the standard Terms field | <input type="checkbox"> | selectable nowhere in the type picker |
radio | no | <input type="radio"> | disabled — no editor for its options |
select | no | <select> | disabled — no editor for its options, so it would render empty |
label | no | <label> holding value | rendered by the partial, not producible anywhere in Leed |
radiogroup | no | one <input type="radiogroup"> per option | same |
checkboxgroup | no | one <input type="checkboxgroup"> per option | same |
hidden | no | <input type="hidden"> | same; emitted after all visible fields |
Where the country list comes from
A countries field renders a <select> filled from leed-form-data.json, a fixed data file shipped by the site builder — 249 entries, each a display name and a lower-case two-letter ISO code, from Afghanistan (af) to Zimbabwe (zw). The value stored on the contact is the code, not the name.
There is no picker for it and no way to shorten or reorder it from the CMS. If you need a restricted list — three countries, or regions rather than nations — a countries field is the wrong tool; use a custom text field with a pattern, or render your own <select> in a template.
Types you cannot pick
checkbox, radio and select are real: they exist in the schema and the site renders them correctly. They are flagged disabled in the type picker because there is no interface for the options list they need, and a select with no options is an empty box. The single exception you can reach is the standard Terms field, which is a checkbox with no options to configure.
Autofill
Two settings on Form Details are both called something like autofill and do entirely different things. They are independent; you can run either, both or neither.
Leed Autofill
With Leed Autofill on, the rendered form asks Leed’s own identity endpoint whether it recognizes this visitor. What happens next depends on how Leed knows them:
- Known from a previous form fill — the matching fields are pre-filled with what they told you last time, and stay editable so they can correct anything.
- Known from anything else — an uploaded contact list, an API or MCP write, email engagement, a CRM sync, a manual entry — every field except Terms is hidden outright and its
requiredflag is dropped.
Either way, the welcome-back message renders above the form, with any {{fieldname}} placeholder in it substituted from the fields on that form. {{firstname}} only resolves if the form actually has a First Name field; a placeholder Leed cannot fill is replaced with an empty string rather than left as literal braces, so the sentence still reads.
Setting Autofill to LinkedIn loads LinkedIn’s autofill.js and an IN/Form2 script that maps LinkedIn’s profile onto your field ids: first name, last name, phone, email, company, title, city, state, country, and postal code (which LinkedIn calls zip). Address is not mapped — LinkedIn does not supply a street address.
The mapping is by field name, so it only reaches the standard fields on the form. A custom field is never autofilled by LinkedIn, and neither is Terms.
Field ids and styling hooks
Every input gets an id of <formId>-<name> — so an Email field on form a1b2c3d4 is a1b2c3d4-email. Radio and checkbox inputs that carry a value get <formId>-<name>-<value> instead, so a set of them stays unique. Ids are what tie each <label> to its input; the name is what gets submitted.
Each field sits in a wrapper carrying leed-form-block and its own type, so div.leed-form-block.textarea selects every textarea block on the site. Everything except Terms additionally carries known-valid-hideable, the class Leed Autofill hides. Between those, the form prototype class and the ids, you have enough handles to style forms with your own CSS without touching Leed’s markup — and if you are rendering forms yourself, the fieldId and turnstileKey helpers generate the same ids the partial does. The form partial documents the markup each type produces in full.
Values that are recorded but have no field
A submission carries more than the fields you added.
otherFieldscollects every submitted name Leed does not recognize as a standard field, stored as JSON on the submission row. This is where your custom fields live, which is why they survive a rename of the field in the builder — and why old rows keep answers to questions you have since deleted.purpose,productNameandtimezoneare first-class columns on the submission even though no standard field produces them.productnameandpurposeare accepted from the payload, so ahiddenfield or a template-rendered form can populate them;timezoneis filled automatically from the browser’s IANA timezone.knownUserrecords whether Leed recognized the visitor at submit time, andverifiedUserrecords the Turnstile verdict. Neither is something the visitor can influence, and neither blocks anything.- The page and page-type the form was submitted from are recorded too, which is what makes the page column on the submissions table — and the per-form performance figures — possible.
The full picture of what Leed then knows about that person, across every form and every visit, is their lead profile.