# Forms

> Discover data-capture form schemas and read their submissions

Canonical URL: https://fa7e86e3d553:3005/tools/forms

> **MCP v3 routing:** The operation names on this page are retained as action-contract references. Do not call them as top-level tools. Pass the former name to `lexsis_discover`, then call the returned router and action with the documented parameters inside `args`.

Read-only tools for discovering data-capture form definitions (email capture, notify-me, newsletter, and any custom forms a merchant has created) and reading their submissions. Use these to check what a store already captures before referencing a form in a page, or to pull leads/signups for reporting.

**These tools are read-only by design.** There is no `create_form_schema` or edit/delete tool — an AI agent unilaterally defining new data-capture forms (arbitrary fields, no human review) is a materially different risk than it reading what a merchant already set up. Creating or editing a form schema is a merchant-only action via the storefront dashboard's **Forms** page.

---

## list_form_schemas

List a store's data-capture form definitions — quizzes, notify-me, lead forms, newsletters, surveys. This is the only way to discover valid `schema_id`s and `form_key`s. Call it before referencing a `schema_id` anywhere, e.g. before `get_form_submissions`.

### Parameters

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `store_id` | string (UUID) | No | Only return schemas for this store (client-side filter; omit for all stores on the tenant) |
| `include_archived` | boolean | No | Include soft-deleted schemas (default `false`) |

### Returns

Array of form schema objects:
```typescript
{
  id: string                       // Schema UUID — use as schema_id elsewhere
  store_id: string
  name: string                     // Human label, e.g. "Skin Type Quiz"
  form_key: string                 // Slug the island posts against, e.g. "email_capture"
  fields: Array<{
    key: string
    type: string                   // text | email | phone | number | select | radio | checkbox | textarea | date
    label: string
    required?: boolean
    placeholder?: string
    options?: string[]
  }>
  settings: Record<string, unknown>
  created_by: string                // "system" | "ai" | "merchant"
  created_at: string
  archived_at: string | null
}
```

### Example

```json
{
  "name": "list_form_schemas",
  "arguments": {
    "store_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
  }
}
```

**Response:**
```json
[
  {
    "id": "a1b2c3d4-...",
    "store_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "name": "Email Capture",
    "form_key": "email_capture",
    "fields": [
      { "key": "email", "type": "email", "label": "Email address", "required": true }
    ],
    "settings": {},
    "created_by": "system",
    "created_at": "2026-07-31T10:00:00Z",
    "archived_at": null
  }
]
```

### Auto-provisioned forms

Three `form_key`s are auto-provisioned by the islands that already ship in every page — you don't need to create these yourself:

| form_key | Captured by | Field |
|----------|-------------|-------|
| `email_capture` | [EmailCapture](/islands/engagement/email-capture) | `email` (required) |
| `notify_me` | [BuyBox](/islands/commerce/buy-box) out-of-stock form | `email` (required) |
| `newsletter` | [Footer](/islands/navigation/footer) newsletter form (hydration mode) | `email` (required) |

A merchant can create additional custom schemas (a quiz, a lead form with more fields) via the dashboard — call `list_form_schemas` to see what exists for a given store before assuming only the three above are available.

### When to Use

- Before building a page, to check whether the store already has a custom form worth referencing in copy or reporting
- Before calling `get_form_submissions`, to resolve a `schema_id` or confirm a `form_key`

---

## get_form_submissions

Read visitor submissions for a form, newest first. Filter by `schema_id` or `form_key` (get either from `list_form_schemas`). Each row has the raw submitted data plus `page_id` and `visitor_id`.

### Parameters

| Param | Type | Required | Description |
|-------|------|----------|-------------|
| `schema_id` | string (UUID) | No | Filter to one form schema |
| `form_key` | string | No | Filter by `form_key` instead of id |
| `limit` | number | No | Max rows (default 50, max 200) |
| `offset` | number | No | Pagination offset (default 0) |

### Returns

Array of submission objects:
```typescript
{
  id: string
  form_key: string
  page_id: string | null
  visitor_id: string | null
  data: Record<string, unknown>    // Raw field values, e.g. {email: "..."}
  created_at: string
}
```

### Example

```json
{
  "name": "get_form_submissions",
  "arguments": {
    "form_key": "notify_me",
    "limit": 20
  }
}
```

**Response:**
```json
[
  {
    "id": "s1a2b3c4-...",
    "form_key": "notify_me",
    "page_id": "p1a2b3c4-...",
    "visitor_id": "v_9f8e7d6c",
    "data": { "email": "shopper@example.com", "product_title": "Hydrating Serum", "variant_id": "gid://shopify/ProductVariant/1" },
    "created_at": "2026-07-31T14:22:00Z"
  }
]
```

### When to Use

- Reporting on lead volume for a specific form or page
- Pulling a list of out-of-stock notify-me signups (`form_key: "notify_me"`) to hand off for restock alerts

---

## Best Practices

1. **Always call `list_form_schemas` first** to resolve a valid `schema_id`/`form_key` — there is no other discovery mechanism.
2. **Don't assume `email_capture` is the only form** — a store may have merchant-created custom schemas; check before you build copy or reporting around a fixed set of forms.
3. **These tools can't create or edit forms.** If a page needs a new kind of data capture (a quiz, a multi-field lead form), tell the merchant to set it up in the dashboard's **Forms** page — do not attempt to route around this by posting arbitrary data through another tool.
