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

# Responses

> Read and delete the responses viewers sent from a page.

A page that contains a `<form data-shareable>` or a `Shareable.submit(…)` call
[collects responses](/guides/collect-responses) from its viewers. These endpoints let the page's
owner read them back and delete them. All endpoints require an `Authorization: Bearer sm_…`
header for the page's owner and live under `https://useshareable.com/api/v1`.

<Note>
  There's no API for *writing* a response. Responses come only from viewers of the published
  page. To close or reopen collection, [update the page](/api-reference/pages#update-a-page) with
  `responses_closed_at`.
</Note>

## List responses

<code>GET /api/v1/pages/{id}/responses</code>

<ParamField query="format" type="string" default="json">
  `json` returns the object below. `csv` returns a CSV file of every matching response (one row
  per response, or per item when a list is split; see `explode`), ready to open in Sheets or
  Excel. `limit` and `offset` don't apply to CSV.
</ParamField>

<ParamField query="explode" type="string">
  The key of a top-level **list of objects** to split into one row per item (for example
  `rows`). Each item's fields become columns, and the response's other fields and respondent
  are copied onto every row. By default the first such list in the responses is split; pass
  `none` to split nothing (the CSV is then one row per response).
</ParamField>

<ParamField query="since" type="string">
  ISO 8601 datetime. Only return responses submitted or replaced **strictly after** it, so an
  agent can fetch just what's new: pass back the newest `submitted_at` you've seen (full
  precision, URL-encoded). With `since`, `total`, `summaries` and the rest cover only the
  responses it returned, not every response on the page.
</ParamField>

<ParamField query="limit" type="number" default="200">
  How many responses (and split rows) to return in this call. Maximum `1000`. JSON only.
  Responses are ordered by when each viewer **first** responded, newest first; a resubmit
  replaces the response but keeps its place.
</ParamField>

<ParamField query="offset" type="number" default="0">
  How many to skip, for paging. Pass the previous call's `next_offset`. JSON only. Paging is
  stable while viewers resubmit: a resubmitted response keeps its place, so it's never skipped or
  repeated. A brand-new response that arrives while you page shifts later pages by one, so you
  may see one response twice at a page boundary (dedupe by `id`), but you never miss one.
  Deleting responses while paging can shift pages the other way.
</ParamField>

```bash theme={null}
curl "https://useshareable.com/api/v1/pages/PAGE_ID/responses?since=2026-10-01T00:00:00Z" \
  -H "Authorization: Bearer $SHAREABLE_API_KEY"
```

```bash Download as CSV, one row per item in "rows" theme={null}
curl "https://useshareable.com/api/v1/pages/PAGE_ID/responses?format=csv&explode=rows" \
  -H "Authorization: Bearer $SHAREABLE_API_KEY" -o responses.csv
```

### Response

The JSON body is `{ "data": { … } }` with these fields. `total`, `fields`, `summaries` (and their
`row_` twins) cover every response the call matched — all of them, or with `since` only the new
ones — while `responses` and `rows` are one page of `limit` from `offset`.

<ResponseField name="status" type="object">
  Whether the page is collecting and how full it is:
  `{ collecting, closed_at, closed, count, bytes, max_count, max_bytes }`. `collecting` is `true`
  when the published HTML contains a `<form data-shareable>` or `Shareable.submit(…)`;
  `closed_at` is the page's `responses_closed_at` and `closed` whether that time has passed.
  `count` and `bytes` are the page's whole store, regardless of `since`; `max_count` and
  `max_bytes` are your plan's limits for one page.
</ResponseField>

<ResponseField name="total" type="number">
  How many responses matched (all of them, or those after `since`).
</ResponseField>

<ResponseField name="fields" type="object[]">
  One entry per field found across the matched responses, in the order they were sent:
  `{ key, label, type }`. `key` is the field's name, with nested objects flattened to dotted keys
  (`scores.clarity`). `label` is the column label from `data-label`, or `null` when there isn't
  one. `type` is the type Shareable inferred from the values: `boolean` (yes/no), `number`,
  `choice`, `multi` (a list of choices), `text`, or `rows` (a list of objects). See
  [how values are shown](/guides/collect-responses#how-values-are-shown).
</ResponseField>

<ResponseField name="summaries" type="object[]">
  One summary per entry in `fields`, each with `key`, `label`, `type` and `answered` (how many
  responses have a value), plus by type: `boolean` → `yes`, `no`; `number` → `mean`, `min`,
  `max`; `choice` / `multi` → `counts: [{ value, count }]`, most common first; `text` →
  `samples: [{ value, respondent }]` (up to 50); `rows` → `items` (total items across responses).
</ResponseField>

<ResponseField name="summary_text" type="string[]">
  The same summaries as one plain line per field, e.g. `• Rating (rating) [number]: 12 answered,
      mean 4.25, min 2, max 5`.
</ResponseField>

<ResponseField name="explodable" type="string[]">
  The top-level keys whose values are lists of objects, i.e. what `explode` accepts.
</ResponseField>

<ResponseField name="explode" type="string | null">
  The key that was split into `rows`, or `null` when nothing was (no such list, or
  `explode=none`).
</ResponseField>

<ResponseField name="row_fields" type="object[]">
  The columns of `rows`: the response's other fields (except any other lists of objects, which
  aren't copied onto rows), then the item's own fields. Same shape as `fields`. Empty when
  nothing was split.
</ResponseField>

<ResponseField name="row_summaries" type="object[]">
  Summaries of the items' own fields across every split row, shaped like `summaries`.
</ResponseField>

<ResponseField name="row_summary_text" type="string[]">
  `row_summaries` as plain lines.
</ResponseField>

<ResponseField name="row_total" type="number">
  How many split rows matched in total.
</ResponseField>

<ResponseField name="responses" type="object[]">
  This page of responses, newest first by first response (see `limit`). Each has:

  <Expandable title="response">
    <ResponseField name="id" type="string">The response ID (use it to delete one).</ResponseField>
    <ResponseField name="respondent" type="string">The viewer's verified email on `email_gate` and `people` pages. On other pages, an anonymous alias (e.g. `Anonymous · 3f9a07c2`) derived from the viewer's device and different on each page. It's a short label for reading, not a unique key: use `id` to tell responses apart.</ResponseField>
    <ResponseField name="name" type="string | null">A display name the viewer gave. Self-reported, not verified.</ResponseField>
    <ResponseField name="submitted_at" type="string">When they last submitted. A resubmit replaces the response and moves this forward; it's what `since` compares against.</ResponseField>
    <ResponseField name="created_at" type="string">When this viewer first responded.</ResponseField>
    <ResponseField name="page_version" type="string | null">The publish time of the page version the viewer had open, as reported by the page.</ResponseField>
    <ResponseField name="path" type="string">The file it was sent from, on a multi-page deck (empty otherwise).</ResponseField>
    <ResponseField name="submit_count" type="number">How many times this viewer has submitted.</ResponseField>
    <ResponseField name="values" type="object">The data flattened to the `fields` keys.</ResponseField>
    <ResponseField name="data" type="object">The object the page sent, as sent.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="rows" type="object[]">
  This page of split rows (empty when nothing was split). Each is
  `{ response_id, respondent, name, submitted_at, item, values }`, where `item` is the 1-based
  position in the list and `values` holds the `row_fields` keys.
</ResponseField>

<ResponseField name="next_offset" type="number | null">
  The `offset` for the next page, or `null` when this was the last.
</ResponseField>

Each viewer has at most **one** response per page; submitting again replaces it. A page holds up
to 100 responses on Free and 10,000 on Pro and Team.

<Tip>
  From an agent, the MCP tool [`get_responses`](/mcp-server#tools) returns the same data plus a
  short summary per field.
</Tip>

## Delete a response

<code>DELETE /api/v1/pages/{id}/responses/{responseId}</code>

Permanently deletes one response. Returns status `204`. That viewer can then respond again.

```bash theme={null}
curl -X DELETE https://useshareable.com/api/v1/pages/PAGE_ID/responses/RESPONSE_ID \
  -H "Authorization: Bearer $SHAREABLE_API_KEY"
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.