# Form Responses

> How to view, export, and analyze form responses. Use when the user asks about submitted data, wants to export responses, or needs response analytics.

- Skill: `builderio/form-responses` (Agent Skill)
- Install (CLI): `npx skillmds@latest add builderio/form-responses`
- Raw SKILL.md: https://api.skillmd.com/api/skills/builderio/form-responses/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: Builder.io (https://skillmd.com/u/builderio)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/builderio/form-responses

---


# Form Responses

## Viewing Responses

Use `list-responses` to see submissions for a specific form:

```bash
pnpm action list-responses --form <form-id> [--limit 50]
```

This shows each response with field labels and values, ordered by submission date (newest first).

For chart/table analytics, prefer `response-insights`:

```bash
# All recent accessible forms
pnpm action response-insights

# One form
pnpm action response-insights --formId <form-id> --days 30 --limit 300
```

`response-insights` returns an explicit first-party widget payload:

- `widget: "data-insights"`
- `chartSeries` for submissions by day
- `table` for recent response rows
- `summary` with total, sampled, and truncation details

Native chat renderers should use that contract for first-party tables/charts.
MCP Apps/iframe rendering is only a fallback for external hosts.

For form setup/configuration previews, use `preview-form`:

```bash
pnpm action preview-form --formId <form-id>
```

It returns a native inline summary/table with the form fields, response count,
status, visibility, and an "Open editor" action.

## Exporting Responses

Use `export-responses` to export to CSV or JSON. The export is uploaded to
configured file storage (never written to local disk — serverless hosts have
a read-only filesystem) and the action returns the resulting file URL:

```bash
# CSV export (default)
pnpm action export-responses --form <form-id>

# JSON export
pnpm action export-responses --form <form-id> --format json
```

The CSV includes headers derived from field labels. Array values (multiselect) are joined with semicolons.

## Response Data Structure

Each response is stored in the `responses` SQL table:

| Column           | Type | Description                          |
| ---------------- | ---- | ------------------------------------ |
| `id`             | text | Unique response ID                   |
| `formId`         | text | Foreign key to the form              |
| `data`           | text | JSON string of field ID -> value map |
| `submittedAt`    | text | ISO timestamp                        |
| `ip`             | text | Submitter IP when available          |
| `submitterEmail` | text | Submitter email hint when known      |
| `pageUrl`        | text | Page the respondent was on, if sent  |
| `clientSurface`  | text | App surface: web, electron, or tauri |

`submitterEmail` may come from the logged-in Forms session or from trusted
feedback clients that pass the logged-in user email as submission metadata.

`pageUrl` and `clientSurface` are hidden pass-through fields. Direct public
fills record the current form URL, while trusted embeds (e.g. the framework
FeedbackButton) forward the respondent's source page and runtime shell (`web`,
`electron`, or `tauri`) so owners can see which screen and app feedback came
from. Sensitive URL query keys are scrubbed before persistence, `clientSurface`
is allowlisted server-side (unknown values are dropped), and anonymous forms
suppress both fields. The responses table surfaces them as "Page" and "Source"
columns when any response carries them.

The `data` JSON maps field IDs to values:

```json
{
  "name": "Alice Smith",
  "email": "alice@example.com",
  "rating": 5,
  "interests": ["design", "development"]
}
```

## Analyzing Responses

To analyze responses, the workflow is:

1. `list-forms` to find the form ID
2. `preview-form --formId <id>` when the question is about setup or fields
3. `response-insights --formId <id>` for counts, daily submissions, and table data
4. Use `list-responses --formId <id>` only when exact row-level inspection is needed
5. Report whether the answer is exact or sampled, including row counts and truncation

## Common Tasks

| User request           | What to do                                                                   |
| ---------------------- | ---------------------------------------------------------------------------- |
| "@Form setup?"         | `preview-form --formId <id>` and answer from the returned fields/settings    |
| "How many responses?"  | `response-insights --formId <id>` and report `summary.responses`             |
| "Export to CSV"        | `export-responses --form <id>`                                               |
| "Submissions by day"   | `response-insights --formId <id> --days 30`                                  |
| "Summarize feedback"   | `response-insights`, then `list-responses` if more detail is needed          |
| "Average rating"       | `list-responses`, compute from rating fields and state the sampled row count |
| "Who submitted today?" | `list-responses`, filter by submittedAt                                      |

## Related Skills

- **form-building** — Understanding the form structure and field types
- **actions** — All response operations go through actions

