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

# Forms

> Create, read, update, and archive forms.

A **form** is an embeddable form bound to one of your verified domains. Forms
are the only resource with full create/update/archive support in v1.

## The form object

```json theme={null}
{
  "id": 123,
  "name": "Contact form",
  "type": "standard",
  "domain": { "id": 5, "domain": "example.com" },
  "submissionCount": 42,
  "fields": [ { "id": "f1", "type": "text", "label": "Name" } ],
  "createdAt": "2026-05-01T12:00:00.000Z",
  "updatedAt": "2026-05-20T09:30:00.000Z"
}
```

`fields` is returned on the single-form view only; list responses omit it for
payload size and include `submissionCount` instead. `domain` is `null` for
legacy unbound forms. `type` is `standard` or `multi-step`.

## List forms

`GET /v1/forms` — scope `read:forms`. Supports `page`, `limit`, and `domainId`
(narrow to one registered domain).

<CodeGroup>
  ```bash curl theme={null}
  curl "https://formitto.com/v1/forms?domainId=5" \
    -H "Authorization: Bearer fmt_live_xxxxxxxx"
  ```

  ```typescript TypeScript theme={null}
  const result = await formitto.forms.listForms({ domainId: 5 });
  ```
</CodeGroup>

## Get a form

`GET /v1/forms/{id}` — scope `read:forms`. Returns the full object including
`fields`.

<CodeGroup>
  ```bash curl theme={null}
  curl https://formitto.com/v1/forms/123 \
    -H "Authorization: Bearer fmt_live_xxxxxxxx"
  ```

  ```typescript TypeScript theme={null}
  const form = await formitto.forms.getForm({ id: 123 });
  ```
</CodeGroup>

## Create a form

`POST /v1/forms` — scope `write:forms`. Requires `name` and a non-empty
`fields` array. `domainId` is optional: if your account has exactly one
verified domain it's auto-selected; with multiple domains, omitting it returns
`400 domain_required` with the candidate list.

<CodeGroup>
  ```bash curl theme={null}
  curl -X POST https://formitto.com/v1/forms \
    -H "Authorization: Bearer fmt_live_xxxxxxxx" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Lead form",
      "fields": [{ "id": "f1", "type": "email", "label": "Email" }],
      "domainId": 5
    }'
  ```

  ```typescript TypeScript theme={null}
  const form = await formitto.forms.createForm({
    name: "Lead form",
    fields: [{ id: "f1", type: "email", label: "Email" }],
    domainId: 5,
  });
  ```
</CodeGroup>

## Update a form

`PATCH /v1/forms/{id}` — scope `write:forms`. Only `name`, `fields`,
`webhookUrl`, and `archived` are mutable. Sending `userId`, `orgId`,
`domainId`, `createdAt`, or `id` returns `400 forbidden_field`.

<CodeGroup>
  ```bash curl theme={null}
  curl -X PATCH https://formitto.com/v1/forms/123 \
    -H "Authorization: Bearer fmt_live_xxxxxxxx" \
    -H "Content-Type: application/json" \
    -d '{ "name": "Renamed form" }'
  ```

  ```typescript TypeScript theme={null}
  const form = await formitto.forms.updateForm({
    id: 123,
    requestBody: { name: "Renamed form" },
  });
  ```
</CodeGroup>

## Archive a form

`DELETE /v1/forms/{id}` — scope `write:forms`. Soft-deletes (archives) the
form; returns `204 No Content`. Archived forms stop serving but their
submissions are preserved.

<CodeGroup>
  ```bash curl theme={null}
  curl -X DELETE https://formitto.com/v1/forms/123 \
    -H "Authorization: Bearer fmt_live_xxxxxxxx"
  ```

  ```typescript TypeScript theme={null}
  await formitto.forms.archiveForm({ id: 123 });
  ```
</CodeGroup>

See [Submissions](/resources/submissions) for reading and ingesting a form's
entries.
