> ## Documentation Index
> Fetch the complete documentation index at: https://docs.os.default.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Forms

> Manage the domains, forms, and submissions your Pixel captures, and review, edit, and publish each form.

Forms is where your Pixel domains, the forms Pixel finds on them, and the submissions they send all
come together. Once Forms is enabled for your workspace, it takes over from the **Pixel** page under
Settings: the same domains, forms, and field mappings you'd manage there now live here instead, with
a dedicated view for managing domains and pages for reviewing, editing, and publishing each form.

<Note>
  Open **Forms** to see your domains, forms, and submissions. Forms is rolling out to workspaces
  gradually, so you may not see it yet, and it's available to admins only.
</Note>

Forms has two tabs, in order: **Domains** and **Forms**. Submissions don't have a tab of their
own: each form's submissions appear on that form's detail page.

## Domains

The **Domains** tab (labeled **Signals** in workspaces on the newer left-sidebar navigation) lists
every website you've connected Pixel to, so you can add new sites, check their connection status,
and manage the pages Pixel tracks on each one.

### Add a domain

<Steps>
  <Step title="Select Add Domain">
    Select **Add Domain** and enter your website address (for example, `https://www.acme.com`).
    This registers the domain so Pixel knows to track it.
  </Step>

  <Step title="Copy the install snippet">
    Default shows the install snippet with your workspace's Pixel public key already filled in.
    Paste it into the `<head>` of every page you want to track, either through your site's own
    template or through a tag manager as a custom HTML tag that fires on all pages.
  </Step>

  <Step title="Select Done">
    Once the snippet is on your site, select **Done** to close the dialog. The domain's status
    updates once Default detects it.
  </Step>
</Steps>

Your workspace has one Pixel public key, so the install snippet is the same on every domain. If your
forms live on more than one domain (for example, `acme.com` and `try.acme.com`), add each one here so
Pixel tracks it, then paste that same snippet on each.

Select **Copy Pixel script** at any time to get the snippet again without starting the add flow over.

### Domain table

Each row shows a domain's **Paths** (tracked paths out of all discovered paths, for example `12 / 12`,
or a dash if none have been discovered yet), the number of **Forms** detected on it, and its **Status**:

| Status       | What it means                                                                           |
| ------------ | --------------------------------------------------------------------------------------- |
| **Active**   | Pixel is installed and confirmed for this domain.                                       |
| **Inactive** | The domain has been added but Pixel hasn't confirmed it's connected yet.                |
| **Error**    | The connection failed. Recheck that the install snippet is on the pages you're testing. |

Use the search box to find a domain by name. Sort by selecting a column header, or open the sort
icon in the toolbar and choose **Domain name** or **Status**, then **Ascending** or **Descending**
(**Clear sort** resets it). Select the filter icon to add a **Status** condition (**Is any of**,
then pick values); active conditions show as chips below the toolbar, with **Clear all** to remove
them.

### View a domain's paths

Select a domain row (domains showing **Error** can't be opened this way) to see the **Paths** Pixel has
discovered on it: each path's slug, the forms found there, and a **Reveal** toggle. Turn off **Reveal**
to stop tracking forms on that specific path without removing the whole domain. Select **View** to
open the live page in a new tab.

Select **Only with forms** to narrow the list to paths where Pixel has actually found a form. Select
more than one row's checkbox to **Enable reveal** or **Disable reveal** on all of them at once, or
**Clear** the selection.

### Remove a domain

Open the menu icon at the end of a domain's row and select **Edit pages** to jump to the same path
view, or **Remove domain** to stop tracking the domain entirely. Removing a domain is a destructive
action: Default stops capturing forms and submissions there right away.

## Forms

The **Forms** tab lists every form Pixel has found across your connected domains, whether it's already
approved and live or still waiting on your review, together in one table.

The table shows each form's name under **Form**, when its **Last submission** came in, its
**Status**, its **Domain**, and when it was **Created**:

| Status           | What it means                                                                             |
| ---------------- | ----------------------------------------------------------------------------------------- |
| **Active**       | The form is live and capturing submissions.                                               |
| **Inactive**     | The form exists but isn't currently capturing submissions.                                |
| **Needs review** | Pixel detected this form on your site; it needs review before it can capture submissions. |

A form can also show a **Changes** badge alongside its status when Pixel has detected field changes on
it that still need review.

Open an approved form's row menu to **Set active** or **Set inactive** without opening its detail page,
or **Delete form** (this can't be undone); the same two actions are also on the form's own detail page.

To act on several forms at once, select their checkboxes. A bar appears with **Set active**,
**Set inactive**, and **Delete**. Deleting asks you to confirm and cannot be undone: submission
capture stops for those forms immediately.

Use the search box to find a form by name or domain. Sort by selecting a column header, or open the
sort icon in the toolbar and choose **Form name**, **Last submission**, **Status**, **Domain**, or
**Created**, then **Ascending** or **Descending** (**Clear sort** resets it). Select the filter icon
to add a **Status** or **Domain** condition (**Is any of**, then pick values); active conditions show
as chips below the toolbar, with **Clear all** to remove them.

### Form field mappings

Select **Field mappings** to open the **Form field mappings** dialog: every detected form field name
mapped to a **Person** or **Company** property, applied across every form that has a field with that
name. Pick a property from the dropdown next to a field, or clear a row to remove its mapping, then
select **Save mappings**.

### Create a form

Select **Create Form** to start a blank form named "Untitled form" with one starter field. Default
creates it and takes you straight to its detail page with the editor already open to **Fields**, so
you can start adding real fields right away.

### Review a new form

Selecting a form that **Needs review** (or opening its row menu and selecting **Review form**) opens
the **Map new form fields** dialog. Search, or filter by **Form**, **Domain**, or **Path**, to narrow a
long list, pick a **Person** or **Company** property for each detected field, then select
**Save changes** to approve the form and store its mappings. Approving a form tells Default this is
the correct shape going forward, so a later change to a field on your site doesn't quietly change what
your workflows receive.

### Form detail

Selecting an already-approved form opens its detail page: the form's name, its status, and how many
submissions it's gotten in the last 30 days.

If Pixel has detected changes to this form's fields on your site, a banner tells you how many field
changes are waiting, with a **Review changes** button.

#### Review detected changes

Select **Review changes** to see exactly what changed: **Renamed fields** (its old name struck through,
then its new one), **Modified fields** (each changed property, before and after), and
**Removed fields**. Any brand new fields appear in their own section so you can map them to
your **Person** or **Company** properties, the same as reviewing a new form. Select
**Approve changes** to update the form to match, or **Dismiss** to leave it as is; either way
your live form on your site is unaffected, only what Default has stored for it changes.

Below that (or in its place, if there's nothing to review), four stat cards summarize the form's
performance: **Submissions (30d)** (with the percent change versus the previous 30 days),
**Known visitors** (the share of submissions from visitors Default already recognized),
**Conversion rate** (the share of visitors who started the form and went on to submit it), and
**Avg time to complete** (with the median shown alongside it).

A **Recent Submissions** table lists each submission's **Person**, **Company**, and when it was
**Submitted**. Select **Load more** to page through older ones.

### Edit Form

Select **Edit Form** on a form's detail page to open its editor, a panel with four tabs, **Fields**,
**Settings**, **Install**, and **Test**, that slides in beside the page.

#### Fields

Shows a reminder that Forms needs Pixel installed on the form's domain to collect submissions and
pre-fill known visitors, with a **Manage Domain** button that jumps straight to that domain on the
**Domains** tab. Below it, every field on the form, in order. Select **Add Field** to add one, then
select it to expand its settings: **Field type** (String, Email, Number, Boolean, Picklist, or
Textarea), **Field name** (must be unique on the form), **Field Label**, **Placeholder text**, and
**Maps to** (the **Person** or **Company** property it writes to; mappings here are global, the same
as **Field mappings**, so changing one updates every form with that field name). Picklist fields also
show a **Picklist options** editor to add, edit, and remove options (select **Add option** for
another, and keep at least one). Every field has a **Required Field** toggle. Drag a field by its
handle to reorder it, or open its menu and select **Delete field** to remove it.

#### Settings

Set the form's **Form name**, see its **Domain**, and turn **Accept submissions**,
**Allow pre-enrichment**, and **Require work email for workflows** on or off.

#### Install

Shows three sections: **Install Pixel**, the same install snippet as **Copy Pixel script** on the
Domains tab (add it to the `<head>` of every page you want to track), **Embed this form**, a
ready-to-use HTML snippet for this specific form that you can paste directly into your site, and
**Use the SDK**, a code sample for submitting this form's responses yourself instead of using the
generated HTML, including how to react to scheduler activity like a booked meeting.

#### Test

Lets you send a real test submission through this form without leaving the editor. Fill in
**Field values** for the form's fields (a dropdown for picklist fields), optionally expand
**UTM parameters** to set UTM values for the test, then select **Run pre-enrichment** to preview
enrichment for the email you entered, or **Send test submission** to submit for real. Test
submissions are real, they appear in **Recent Submissions** and run any live workflows attached to
the form.

{/* verified against product (origin/main @ 36d98c7b2, 2026-07-24):
   Tab labels (Domains, Forms) + routes → apps/default-fe/src/app/(apps)/@forms/forms/_constants/forms-tabs.tsx:12-24
     (id 'domains' label "Domains" routes to /forms/signals; id 'forms' label "Forms" routes to /forms;
     the 'form-builder' and 'submissions' tabs that used to exist here are gone, see NOTES.md)
   Entry point + admin/FORMS_APP gating; Dock vs. sidebar shell modes coexist →
     apps/default-fe/src/app/(apps)/@forms/forms/layout.tsx:10-24,
     apps/default-fe/src/app/(apps)/@forms/forms/FormsAppLayoutClient.tsx:13-75,
     apps/default-fe/src/common/components/shell/ShellModeContext.tsx,
     apps/default-fe/src/app/(apps)/layout.tsx:102-154 (NAV_V2 flag on the server picks the mode),
     apps/default-fe/src/lib/feature-flags.ts:31-34 (NAV_V2 = 'nav-v2', rolled out per org)
   "Signals" sidebar label (nav-v2 mode) + Dock placement (Workflows, Forms, Settings) →
     apps/default-fe/src/common/registry/AppRegistry.tsx:435-480 ([Apps.FORMS] nav: 'forms' order 30, 'signals' order 31),
     apps/default-fe/src/common/components/Dock/index.tsx:86-96
   Domains tab labels (Add Domain, Copy Pixel script, table columns, status labels, sort/filter) →
     apps/default-fe/src/app/(apps)/@forms/forms/signals/_components/{DomainsView,DomainsToolbar,PixelDomainsTable,domain-utils}.tsx
   Add-domain dialog + Copy Pixel script dialog → apps/default-fe/src/app/(apps)/@settings/settings/(configurations)/pixel/_components/{AddDomainModal,CopyScriptModal}.tsx
   Domain detail / Paths / Reveal / Only with forms filter / bulk Enable reveal, Disable reveal, Clear →
     apps/default-fe/src/app/(apps)/@settings/settings/(configurations)/pixel/_components/DomainDetailModal.tsx:228-249,268-284
   Copy domain UUID (internal-debug gated, not documented) → forms/signals/_components/PixelDomainsTable.tsx:228,259-267
   Forms tab table + toolbar (search, sort, Create Form) → forms/_components/{FormsView.tsx,FormsTable.tsx,FormsToolbar.tsx,forms-utils.ts}
   Forms tab filter (Status/Domain, "Is any of", chips, Clear all) → forms/_components/forms-filter-fields.ts:16-33,
     packages/ui/src/composed/filters/{FilterTrigger.tsx,FilterDropdown.tsx,FilterChip.tsx,FilterBar.tsx:93-94}
   Create Form flow (Untitled form + starter field, ?new=1 auto-opens the editor) →
     forms/_components/FormsView.tsx:78-92 (handleCreateForm),
     apps/default-fe/src/app/(apps)/@forms/forms/[formId]/_components/FormDetailView.tsx:45-53
   Row actions Set active/Set inactive, Delete form (Copy form UUID internal-debug, not documented) →
     forms/_components/FormActions.tsx
   Form field mappings dialog (global editor) → .../forms/forms/_components/{FormFieldMappingsDialog,mapping-utils,useFormCaptureMappingOptions}.tsx
   Review a new form / Map new form fields dialog → apps/default-fe/src/app/(apps)/@settings/settings/(configurations)/pixel/_components/DetectedFieldsDialog.tsx:119,126,295,366
   Form detail page (header, Preview disabled "Coming soon", banner, stat cards, submissions table) →
     apps/default-fe/src/app/(apps)/@forms/forms/[formId]/_components/{FormDetailView.tsx:131-160,FormStatCards,FormSubmissionsTable,detail-utils,changes-utils}.tsx
   Review detected changes dialog → apps/default-fe/src/app/(apps)/@forms/forms/[formId]/_components/FormChangesDialog.tsx:143-149,271-276
   Edit Form panel tabs (Fields, Settings, Install, Test) →
     apps/default-fe/src/app/(apps)/@forms/forms/[formId]/_components/editor/FormEditorPanel.tsx:83-109
   Fields tab (Manage Domain banner, Add Field, Delete field; Copy field UUID internal-debug, not documented) →
     editor/FieldsTab.tsx:116-160, editor/FieldRow.tsx:161-187
   Field editor (Field type selector + list, editable Field name, Field Label, Placeholder text, Maps to, Picklist options,
     Required Field) → editor/FieldRowEditor.tsx:180-335, editor/editor-utils.ts:21-30
   Settings tab → editor/SettingsTab.tsx
   Install tab (Install Pixel / Embed this form / Use the SDK) → editor/PublishTab.tsx:82-136, editor/publish-snippets.ts
     (scheduler behavior described by function only; the internal service name in useChronosUrl/chronos-url.tsx is never
     surfaced in the SDK snippet or in this doc)
   Test tab (Field values, UTM parameters, Run pre-enrichment, Send test submission) → editor/TestTab.tsx:244-355

   RE-VERIFIED 2026-08-01 against origin/main. Three commits landed on this surface after the
   2026-07-26 pass and four claims were patched. The old paths in the citations above still
   resolve except where noted.
     #3061 (b6c5c258b) rewrote the forms table on the events-table canon. FormsTable.tsx is now
       FormsTable/ (index.tsx, columns.tsx, cells/, BulkActionsToolbar.tsx, types.ts).
       PATCHED: the row description. Columns per columns.tsx are select, Form, Last submission,
       Status, Domain, Created, actions. There is no submissions-count column, so the old
       "Submissions in the last 24h" claim was wrong in both the number and the window. The
       30-day figure on the DETAIL page is separate and still correct, FormStatCards.tsx:71
       renders "Submissions (30d)".
       PATCHED: added the bulk actions paragraph. Selecting rows opens a BulkActionsBar with
       Set active, Set inactive, and a destructive Delete, whose confirm copy is "This action
       cannot be undone. Submission capture stops for these forms immediately"
       → FormsTable/BulkActionsToolbar.tsx:118-133,140-150.
     #3062 (1f7d9069c) put the domains table on the same kit.
       PATCHED: "Filter by status" is gone. Domains now use the same canonical FilterTrigger as
       Forms, one Status field with the "Is any of" operator and Active / Inactive / Error
       values → signals/_components/domain-filter-fields.ts. Sort labels are unchanged
       (Domain name, Status) → DomainsToolbar.tsx:29-32.
     PATCHED in both sections: sorting is now available from the column header as well as the
       toolbar dropdown. One TanStack sorting state drives both, stated in the prop comment on
       each toolbar and in SortableTableHeaders.tsx (added by #3061).
     #3057 (8602834ab) was button and icon styling only. It removed a disabled History
       placeholder from both toolbars, which this page never documented, so nothing to change.
     Forms toolbar sort fields are Form name, Last submission, Status, Domain, Created
       → FormsToolbar.tsx:33-39. The old list named a "Submissions" option that no longer
       exists.

   PIXEL KEY SCOPE corrected 2026-08-02, in answer to the Greptile review on PR for step 12
   (valid). The Add-a-domain steps said "Default creates a unique Pixel, with its own public key,
   for that domain". There is exactly ONE pixel public key per organization and adding a domain
   does not mint another:
     ensurePixelPublicKey(organizationId) in apps/default-api/src/server/modules/domains/
       mutations.ts:18-44 updates controlplane_projects.pixel_public_key WHERE org_id = ? AND
       pixel_public_key IS NULL, then falls through to SELECT the existing value. So the first
       domain mints the key and every later domain returns the same one.
     domains/mutations.ts:85,107 returns that org key as `pixelPublicKey` on createDomain, which
       is what AddDomainModal.tsx:37 puts in the snippet, and domains/router.ts:15 returns the
       same org key for the standalone Copy Pixel script path.
     packages/core-db/src/schema/domains/index.ts:12-26 has no key column at all: id, org_id,
       domain, status, created_by, updated_by. There is nowhere for a per-domain key to live.
   So registering a domain tells Pixel which hostnames to track; it does not change the snippet.
   The page now says that outright, because the wrong model leads an admin to hunt for a second
   snippet they will never find.
   INHERITED, NOT FIXED HERE: settings/pixel.mdx (live) is where this wording came from and still
   carries it at lines 30, 33, 63, and most explicitly 92 ("One snippet per domain. Each domain
   you add has its own snippet and key"). Same page also calls the key a `pk_...` value at line
   88, but ensurePixelPublicKey mints a bare randomUUID() with no prefix. Flagged to the operator
   as a separate scope decision, since it is a live page outside this PR. */}
