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

# Forms

> Read forms and the submissions captured by them

Forms collect structured data from your users — typically lead capture, surveys, or onboarding flows. The Forms API is **read-only**: forms themselves are configured in the dashboard (see the [Forms feature docs](/features/forms/overview)), and submissions are created when users fill them out. The API lets you list forms, fetch a single form's configuration, and read submissions.

## The Form object

<ResponseField name="id" type="string" />

<ResponseField name="workspace_id" type="string" />

<ResponseField name="bot_id" type="string">The agent that owns this form.</ResponseField>

<ResponseField name="name" type="string" />

<ResponseField name="description" type="string | null" />

<ResponseField name="standard_fields" type="object">
  Configuration for built-in fields (name, email, phone, etc.) — JSON shape varies by form.
</ResponseField>

<ResponseField name="custom_fields" type="object">
  Configuration for custom fields the workspace has defined.
</ResponseField>

<ResponseField name="survey_questions" type="object">
  Configuration for survey questions, if the form is a survey form.
</ResponseField>

<ResponseField name="created_at" type="string">ISO 8601 timestamp.</ResponseField>
<ResponseField name="updated_at" type="string">ISO 8601 timestamp.</ResponseField>

## The Submission object

<ResponseField name="id" type="string" />

<ResponseField name="form_id" type="string" />

<ResponseField name="contact_id" type="string | null">
  Linked contact, if the submission was associated with one.
</ResponseField>

<ResponseField name="custom_field_responses" type="object">
  The submitter's answers, keyed by field name.
</ResponseField>

<ResponseField name="is_internal" type="boolean">
  `true` if the submission was created by an internal user (e.g. via dashboard testing). Filtered out of submission lists by default.
</ResponseField>

<ResponseField name="submitted_at" type="string">ISO 8601 timestamp.</ResponseField>

***

## List forms

<ParamField path="method" type="GET">
  `GET /api/v1/forms`
</ParamField>

### Query parameters

| Param       | Type    | Description                                 |
| ----------- | ------- | ------------------------------------------- |
| `bot_id`    | string  | Restrict to forms owned by a specific agent |
| `page`      | integer | See [Pagination](/api-reference/pagination) |
| `page_size` | integer | See [Pagination](/api-reference/pagination) |

### Example

```bash theme={null}
curl https://clarky.ai/api/v1/forms \
  -H "Authorization: Bearer ck_live_example"
```

```json theme={null}
{
  "data": [
    {
      "id": "f_01HFRM...",
      "workspace_id": "w_01HXXX...",
      "bot_id": "b_01HDEF...",
      "name": "Demo Request",
      "description": "Lead capture form for the marketing site",
      "standard_fields": {
        "first_name": { "enabled": true, "required": true },
        "email": { "enabled": true, "required": true }
      },
      "custom_fields": {},
      "survey_questions": {},
      "created_at": "2026-02-10T10:00:00.000Z",
      "updated_at": "2026-04-15T08:00:00.000Z"
    }
  ],
  "pagination": { "page": 1, "page_size": 25, "total": 1, "total_pages": 1 }
}
```

***

## Get a form

<ParamField path="method" type="GET">
  `GET /api/v1/forms/{id}`
</ParamField>

Returns the full form configuration, including every standard, custom, and survey field.

### Example

```bash theme={null}
curl https://clarky.ai/api/v1/forms/f_01HFRM \
  -H "Authorization: Bearer ck_live_example"
```

```json theme={null}
{
  "data": {
    "id": "f_01HFRM...",
    "workspace_id": "w_01HXXX...",
    "bot_id": "b_01HDEF...",
    "name": "Demo Request",
    "description": "Lead capture form for the marketing site",
    "standard_fields": {
      "first_name": { "enabled": true, "required": true },
      "last_name": { "enabled": true, "required": false },
      "email": { "enabled": true, "required": true },
      "company": { "enabled": true, "required": false }
    },
    "custom_fields": {
      "team_size": {
        "label": "How big is your team?",
        "type": "select",
        "options": ["1-10", "11-50", "51-200", "200+"]
      }
    },
    "survey_questions": {},
    "created_at": "2026-02-10T10:00:00.000Z",
    "updated_at": "2026-04-15T08:00:00.000Z"
  }
}
```

***

## List form submissions

<ParamField path="method" type="GET">
  `GET /api/v1/forms/{id}/submissions`
</ParamField>

Returns a paginated list of submissions for a single form, in reverse-chronological order.

### Query parameters

| Param              | Type    | Description                                                    |
| ------------------ | ------- | -------------------------------------------------------------- |
| `include_internal` | boolean | Include submissions where `is_internal=true` (default `false`) |
| `page`             | integer | See [Pagination](/api-reference/pagination)                    |
| `page_size`        | integer | See [Pagination](/api-reference/pagination)                    |

### Example

```bash theme={null}
curl "https://clarky.ai/api/v1/forms/f_01HFRM/submissions?page_size=50" \
  -H "Authorization: Bearer ck_live_example"
```

```json theme={null}
{
  "data": [
    {
      "id": "s_01HSUB...",
      "form_id": "f_01HFRM...",
      "contact_id": "c_01HXYZ...",
      "custom_field_responses": {
        "first_name": "Ada",
        "email": "ada@example.com",
        "company": "Analytical Engines Inc.",
        "team_size": "11-50"
      },
      "is_internal": false,
      "submitted_at": "2026-04-29T13:00:00.000Z"
    }
  ],
  "pagination": { "page": 1, "page_size": 50, "total": 1, "total_pages": 1 }
}
```

<Note>
  By default, submissions where `is_internal=true` (typically internal test fills from the dashboard) are excluded. Pass `include_internal=true` to see them — useful when reconciling totals against the dashboard's "include internal" toggle.
</Note>

***

## Get a submission

<ParamField path="method" type="GET">
  `GET /api/v1/submissions/{id}`
</ParamField>

### Example

```bash theme={null}
curl https://clarky.ai/api/v1/submissions/s_01HSUB \
  -H "Authorization: Bearer ck_live_example"
```

```json theme={null}
{
  "data": {
    "id": "s_01HSUB...",
    "form_id": "f_01HFRM...",
    "contact_id": "c_01HXYZ...",
    "custom_field_responses": {
      "first_name": "Ada",
      "email": "ada@example.com",
      "company": "Analytical Engines Inc.",
      "team_size": "11-50"
    },
    "is_internal": false,
    "submitted_at": "2026-04-29T13:00:00.000Z"
  }
}
```

<Tip>
  To get notified the moment a new submission lands — instead of polling — set up a [Webhook](/features/settings/webhooks) on the contact-created or form-submission events.
</Tip>
