> For the complete documentation index, see [llms.txt](https://docs.peakcommerce.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.peakcommerce.com/product/journeys-and-pages/journey-steps/signup-form-fields.md).

# Signup Form Fields

The **signup form field editor** controls exactly what a journey's signup form collects and how each field validates — which fields appear, in what order and layout, whether each is required, what format its value must match, and what error message the visitor sees when it doesn't. Because the same field definitions drive the live form, the editor's preview, **and** the server-side check on every submission, what you configure here is precisely what runs in production — there is no drift between the form a visitor sees and the rules that gate their advance.

You need it whenever the default signup form (First Name, Last Name, Email, Phone, Company) isn't enough: collecting a billing address for tax, a job title for lead scoring, a website for enrichment — or simply tightening what an existing field accepts.

<figure><img src="/files/f9oyWEw7mQLV4azNetqx" alt="The signup form field editor with the field tray and per-field settings on the left and the live form preview on the right"><figcaption><p>The Field validation editor — field chips and per-field settings on the left, and a live preview on the right that doubles as the drag-and-drop surface and validates exactly like the published form.</p></figcaption></figure>

## Open the editor

1. Open the journey builder: **Content → Journeys → Edit → Steps**.
2. Expand a step that has the **Signup** [role](/product/journeys-and-pages/journey-steps/journey-step-types.md) — it shows a **Field validation** panel ("which fields are collected and what data each accepts").
3. Click **Edit field validation**. The editor opens full-window, with **Cancel** and **Save changes** in the top bar and the step's breadcrumb below it.

An *Unsaved changes* pill appears once you edit; **Save changes** stays disabled until there is something to save.

## The three panels

* **Field tray** (top left) — every defined field as a chip. **Solid** chips are on the form; **dashed** chips are defined but not currently collected. A red `*` marks required fields. Click a chip to select it for editing.
* **Detail panel** (below the tray) — edits the selected field's properties. The header shows the field's label, its context key (e.g. `{{email}}`), a **core** badge for the five built-in fields, and an **On the form / Not collected** state pill.
* **Live preview** (right) — a working copy of the signup form. It's not just a picture: it is the **drag-and-drop surface** for building the form, and it validates input with the exact rules the live form ships.

A **Component config** card under the preview shows the raw saved configuration, if you want to see precisely what persists.

## Place, reorder, and remove fields

Everything is drag-and-drop, with click-only equivalents in the detail panel:

* **Place a field** — drag its chip from the tray into the preview. Drop it on an existing field to insert at that position, or on empty space to append. Or select the chip and click **Place at end of form**.
* **Reorder** — drag a field within the preview to a new position.
* **Remove from the form** — drag a placed field from the preview back onto the tray, or click **Take off the form**. The field stays defined (dashed chip) so you can put it back later without reconfiguring it.
* **Delete** — custom fields (not the five core ones) also have a **Delete field** button that removes the definition entirely.

The count badge in the tray header ("*N* on form") tracks how many fields are currently collected.

## Per-field settings

Select a field to edit:

* **Requirement** — `required` or `optional`. A required field must be filled in before the visitor can advance; an optional field may be left empty, but a non-empty value still has to match the format.
* **Accepted format** — the validation rule for non-empty values:

  | Format     | Accepts                                                                 |
  | ---------- | ----------------------------------------------------------------------- |
  | `name`     | Letters (any alphabet), plus spaces, hyphens, apostrophes, and periods  |
  | `email`    | A valid email address (`user@domain.tld`)                               |
  | `phone`    | 7–15 digits; `+`, parentheses, hyphens, periods, and spaces are allowed |
  | `number`   | Digits only                                                             |
  | `text`     | Any non-empty value                                                     |
  | `any`      | No check at all                                                         |
  | `url`      | A web address starting with `http://` or `https://`                     |
  | `postal`   | 3–10 letters/digits (hyphens and spaces allowed)                        |
  | `password` | At least 8 characters; the input is masked                              |

  The `password` format isn't offered for new fields — it appears in the picker only on a field that already uses it.
* **Width** — `full row` or `half row`. The form lays out on a two-column grid; half-row fields sit side by side (e.g. First Name / Last Name), full-row fields span both columns.
* **Label** — the caption shown above the input on the form.
* **Custom error message** — shown when the field fails validation (required-but-empty or format mismatch). Leave blank to use the format's default message (e.g. *"Please enter a valid email address."*).

Each field also carries a **placeholder** — the hint text inside the empty input, shown in the preview exactly as it will render. New fields default their placeholder to the field's label.

## Add fields

Click **+ Add field** to open the palette:

* **Presets** — one-click definitions with sensible keys, formats, and widths: **Street Address**, **City**, **Postal Code**, **Country**, **Job Title**, and **Website**. A preset is greyed out once it's already defined.
* **Custom field** — enter a label and pick an accepted format, then click **Add custom**. The field's context key is derived from the label (e.g. *VAT Number* → `vatNumber`); that key is the journey-context variable the submitted value is written to, so later steps and commerce actions can map it.

  Keys that the journey engine already owns — such as `sessionId`, `journeyId`, `currency`, `selectedPlan`, `productId`, `contactId`, and the UTM parameters — are **reserved and blocked**: the editor rejects the label with an explanation rather than let a form field silently overwrite engine state.

New fields land in the tray **unplaced** (dashed) and selected — drag them into the preview or click **Place at end of form** to collect them.

## Test in the live preview

Type into the preview's inputs and click **Continue**. The preview validates every placed field with the same rules the published form uses:

* Failures highlight the field and show the exact error message a visitor would see — including your custom messages.
* When everything passes, a banner confirms: **"All fields valid — Continue would advance."**

Preview input is session-only; it is never saved with the configuration.

## Server-side enforcement

Validation is not just in the browser. Every submission to the journey's public advance endpoint is checked **server-side against the same field configuration** — required fields must be present, and non-empty values must satisfy their format. A request that bypasses the form entirely is held to the same rules the form displays.

## Who uses this, and when

* **Journey admins** shaping what a signup step collects — before launch, or any time the downstream systems need a new attribute.
* **Marketing / RevOps** tightening lead quality (e.g. switching Company to required, or adding Website with the `url` format so enrichment gets clean input).

## Gotchas

* **Only placed fields persist.** When you save, the configuration stores the fields that are *on the form*, in order. The five core fields always reappear in the tray as dashed chips even when off the form — but a **custom** field you defined and never placed will not survive the save. Place it (or note its settings) before saving.
* **Removing a field an action still uses.** If a step's commerce actions map a field from context (for example, an integration action reading `email`), taking that field off the form shows a warning listing the affected operations. You can still save — it's a warning, not a block — but those actions will receive **no value** at run time. Review the step's [commerce action](/product/journeys-and-pages/journey-steps/commerce-actions.md) field mappings before removing a field.
* **Custom error messages replace both failure messages.** The same custom message is shown for "required but empty" and for a format mismatch — write it so it covers both, or leave it blank and let the per-case defaults do the work.
* **Reserved keys are checked at save as well as in the editor** — a configuration that tries to write a reserved context key is rejected outright rather than partially applied.

## Related pages

* [Step Roles](/product/journeys-and-pages/journey-steps/journey-step-types.md) — the Signup role, which unlocks this editor.
* [Managing Journey Steps](/product/journeys-and-pages/journey-steps/managing-journey-steps.md) — input/output variables and step data flow.
* [Commerce Actions](/product/journeys-and-pages/journey-steps/commerce-actions.md) — how the collected values feed the step's operations.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.peakcommerce.com/product/journeys-and-pages/journey-steps/signup-form-fields.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
