# CRM forms

Read and configure CRM forms, publish them on a website and submit visitor data to them.

**Scope:** `crm` | **Base URL:** `https://vibecode.bitrix24.com/v1` | **Authorization:** `X-Api-Key`

## Documentation sections

- [Form management](/docs/entities/crm-forms/management) — create, read, update, validate, activate and delete forms
- [Builder dictionaries](/docs/entities/crm-forms/builder) — form properties, CRM entity fields, Bitrix24 account settings and scenarios
- [Publishing and results](/docs/entities/crm-forms/publishing) — embedding code, website widgets, Open Channels and visitor data submission

## Key fields

| Field | Description |
|------|----------|
| `id` | Form ID. List: [`GET /v1/crm-forms`](./crm-forms/list.md) |
| `name` | Form name in the list of forms |
| `active` | Whether the form is active. Can be changed only through [activation](./crm-forms/activate.md) and [deactivation](./crm-forms/deactivate.md) |
| `updatedTime` | Time of the last change. Passed in write requests to protect against overwriting someone else's changes |
| `fields[].name` | Form field name, for example `LEAD_NAME`, `LEAD_PHONE` |
| `fields[].required` | Whether the field is required for submission |
| `responsible.userIds` | Users responsible for the form's results. List: [`GET /v1/users`](/docs/entities/users) |

To read a full form or select specific properties, see [Get a form](./crm-forms/get.md). [Form contract fields](./crm-forms/fields.md) lists top-level metadata only. Take nested property names and values from the full GET response for your configured form.

## What to know before you start

1. A read-only key can use GET requests and both form validations — `POST /v1/crm-forms/validate` and `POST /v1/crm-forms/:id/validate`. Creating, updating, activating or deactivating, deleting and submitting visitor data require a key with write access. Submitting visitor data can create CRM records and trigger automation and notifications.
2. Without filters, the list includes active and inactive forms and returns one page. By default, it returns 11 scalar fields. Use `select`, for example `id,name,crm.entityScheme,responsible.userIds,updatedTime`, to request sections or subfields. Bitrix24 validates filters, sorting and pagination.
3. A full form contains the 11 scalar fields and 14 configuration sections, including `analytics`, `integrations` and `spamProtection`. The object is passed through without rebuilding agreements, adding top-level aliases or filling missing fields. An explicit `select` can return a partial object without `id`, `name` or `fields`.
4. User content, public URLs and embedding signatures are preserved. Only credentials for the current Bitrix24 connection are replaced, with affected paths in `meta.redacted`. Such a response is not a complete configuration for saving back. Credentials are always hidden in errors and logs.
5. For an update, first read the form and keep `updatedTime`. Activate and deactivate return the actual `active` and `updatedTime`, including the unchanged version when no write was needed. If the additional read after a confirmed create or update fails, the response remains successful with `data.id` and `meta.warnings`. Read the form before the next write, without repeating the successful operation.
6. Create, update, validate and embedding-update requests accept a flat body or an object-valued `fields` wrapper. For versioned updates, keep `updatedTime` at the root. The form's own `fields` array remains a form property. Bitrix24 validates settings and business rules.
7. `CRM_FORM_PARTIALLY_CREATED` is an error: the form already exists; its ID is in `error.id`. GET the form, then correct or delete it. Do not repeat creation. There is no automatic deletion or retry.

## Limits

| Limit | Value |
|-------|----------|
| Forms per list page | Bitrix24 defaults when `limit` and `offset` are omitted. Both parameters are optional and validated by Bitrix24 |
| Active forms | `limits.activeForms` in the [builder configuration](./crm-forms/configuration.md) |
| Deletion | irreversible; an active form is deleted only with `confirm=true` or `confirmed=true` |
| Request rate | shared across the Vibecode API — see [Limits and optimization](/docs/optimization) |

## Quick start

Get the first two forms in your Bitrix24 account:

```bash
curl 'https://vibecode.bitrix24.com/v1/crm-forms?limit=2' \
  -H 'X-Api-Key: YOUR_API_KEY'
```

```json
{
  "success": true,
  "data": [
    {
      "id": 1,
      "code": "1_kontaktnye_dannye",
      "name": "Contact details",
      "active": true,
      "system": true,
      "languageId": "ru",
      "templateId": "light",
      "createdTime": "2020-04-22T06:13:05Z",
      "updatedTime": "2020-04-22T06:13:05Z",
      "activeChangedById": 1,
      "activeChangedTime": "2020-04-22T06:13:05Z"
    },
    {
      "id": 3,
      "code": "3_obratnaya_svyaz",
      "name": "Feedback form",
      "active": true,
      "system": true,
      "languageId": "ru",
      "templateId": "light",
      "createdTime": "2020-04-22T06:13:05Z",
      "updatedTime": "2020-04-22T06:13:05Z",
      "activeChangedById": 1,
      "activeChangedTime": "2020-04-22T06:13:05Z"
    }
  ]
}
```

Live response from a Russian-language portal: `code` and `languageId` are portal values returned as stored. `code` is the exact value for the `?code=` filter, and another portal has its own codes. Only the display `name` appears here in English.

## Full example

Validate a draft, create an inactive form, activate it, submit visitor data, deactivate it and delete it.

1. Validate the draft without saving it:

```bash
curl -X POST 'https://vibecode.bitrix24.com/v1/crm-forms/validate' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Contact form","crm":{"entityScheme":1},"fields":[{"name":"LEAD_NAME","type":"string","label":"Name","required":true,"multiple":false},{"name":"LEAD_PHONE","type":"phone","label":"Phone","required":false,"multiple":false}]}'
```

```json
{ "success": true, "data": { "valid": true, "violations": [] } }
```

2. Create the form inactive — with the same body plus `"active":false`:

```bash
curl -X POST 'https://vibecode.bitrix24.com/v1/crm-forms' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"name":"Contact form","active":false,"crm":{"entityScheme":1},"fields":[{"name":"LEAD_NAME","type":"string","label":"Name","required":true,"multiple":false},{"name":"LEAD_PHONE","type":"phone","label":"Phone","required":false,"multiple":false}]}'
```

The `201` response contains the saved form, or `data.id` with `meta.warnings` if the additional read failed. Keep `data.id`, which is `87` in this example. A warning does not mean creation failed: GET the form instead of repeating POST. If creation returns `CRM_FORM_PARTIALLY_CREATED`, use `error.id` to read and correct or delete the existing form, without repeating creation.

3. Activate the form:

```bash
curl -X POST 'https://vibecode.bitrix24.com/v1/crm-forms/87/activate' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
```

```json
{ "success": true, "data": { "active": true, "updatedTime": "2026-10-27T13:48:44Z" } }
```

4. Submit visitor data:

```bash
curl -X POST 'https://vibecode.bitrix24.com/v1/crm-forms/87/results' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"fields":{"LEAD_NAME":"Anna","LEAD_PHONE":"+12025550123"},"fromUrl":"https://example.com/contact"}'
```

```json
{ "success": true, "data": { "resultId": 235 } }
```

5. Deactivate the form:

```bash
curl -X POST 'https://vibecode.bitrix24.com/v1/crm-forms/87/deactivate' \
  -H 'X-Api-Key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{}'
```

```json
{ "success": true, "data": { "active": false, "updatedTime": "2026-10-27T13:48:46Z" } }
```

6. Delete the form. An inactive form is deleted without `confirm`:

```bash
curl -X DELETE 'https://vibecode.bitrix24.com/v1/crm-forms/87' \
  -H 'X-Api-Key: YOUR_API_KEY'
```

```json
{ "success": true, "data": { "deleted": true } }
```

## Endpoint reference

| Method | Path | Bitrix24 method | Description |
|-------|------|---------------|----------|
| POST | [`/v1/crm-forms`](/docs/entities/crm-forms/create) | `crm.form.add` | Create a form |
| GET | [`/v1/crm-forms`](/docs/entities/crm-forms/list) | `crm.form.list` | List forms |
| GET | [`/v1/crm-forms/:id`](/docs/entities/crm-forms/get) | `crm.form.get` | Get a form |
| PATCH | [`/v1/crm-forms/:id`](/docs/entities/crm-forms/update) | `crm.form.update` | Update a form |
| DELETE | [`/v1/crm-forms/:id`](/docs/entities/crm-forms/delete) | `crm.form.delete` | Delete a form |
| POST | [`/v1/crm-forms/validate`](/docs/entities/crm-forms/validate) | `crm.form.validate` | Validate a form without saving it |
| POST | [`/v1/crm-forms/:id/activate`](/docs/entities/crm-forms/activate) | `crm.form.activate` | Activate a form |
| POST | [`/v1/crm-forms/:id/deactivate`](/docs/entities/crm-forms/deactivate) | `crm.form.deactivate` | Deactivate a form |
| GET | [`/v1/crm-forms/fields`](/docs/entities/crm-forms/fields) | `crm.form.field.list` | Form contract fields |
| GET | [`/v1/crm-forms/fields/:name`](/docs/entities/crm-forms/field) | `crm.form.field.get` | Get a form contract field |
| GET | [`/v1/crm-forms/configuration`](/docs/entities/crm-forms/configuration) | `crm.form.configuration.get` | Get the builder configuration |
| GET | [`/v1/crm-forms/entity-fields`](/docs/entities/crm-forms/entity-fields) | `crm.form.entityfield.list` | List entity fields |
| GET | [`/v1/crm-forms/scenarios`](/docs/entities/crm-forms/scenarios) | `crm.form.scenario.list` | List scenarios |
| GET | [`/v1/crm-forms/scenario-categories`](/docs/entities/crm-forms/scenario-categories) | `crm.form.scenariocategory.list` | List scenario categories |
| GET | [`/v1/crm-forms/:id/embedding`](/docs/entities/crm-forms/embedding) | `crm.form.embedding.get` | Embedding code |
| PATCH | [`/v1/crm-forms/:id/embedding`](/docs/entities/crm-forms/embedding-update) | `crm.form.embedding.update` | Embedding settings |
| GET | [`/v1/crm-forms/:id/site-buttons`](/docs/entities/crm-forms/site-buttons) | `crm.form.sitebutton.list` | Website widgets |
| GET | [`/v1/crm-forms/:id/openlines`](/docs/entities/crm-forms/openlines) | `crm.form.openline.list` | Open Channels for a form |
| POST | [`/v1/crm-forms/:id/results`](/docs/entities/crm-forms/results) | `crm.webform.result.add` | Submit visitor data, REST v2 |

The PRD name `crm.form.embed.get` maps to `crm.form.embedding.get`. The PRD name `crm.form.fields.get` for fields of selected CRM entities maps to `crm.form.entityfield.list`. `crm.form.field.list` and `crm.form.field.get` describe the form model itself. Visitor submissions use REST v2 and are separate from these REST v3 methods.

## Error codes

### CRM form errors

| HTTP | Code | When |
|------|-----|-------|
| 400 | `INVALID_PARAMS` | Invalid request structure or a parameter rejected by Bitrix24. The original code is in `error.b24Code`, with field diagnostics in `error.validation` when supplied |
| 400 | `CRM_FORM_PARTIALLY_CREATED` | The form exists, but some settings were not saved. GET the form by `error.id`, then correct or delete it. Do not repeat creation |
| 402 | `CRM_FORM_WRITE_RESTRICTED` | The Bitrix24 plan (free or demo) does not allow writing CRM forms |
| 402 | `CRM_FORM_ACTIVATION_LIMIT_REACHED` | The active-form limit has been reached |
| 403 | `CRM_FORM_SYSTEM_IMMUTABLE` | A system form cannot be updated or deleted |
| 409 | `CRM_FORM_VERSION_MISMATCH` | The form changed after it was read. The current version is in `error.currentUpdatedTime` |
| 409 | `CRM_FORM_DELETE_CONFIRMATION_REQUIRED` | An active form is deleted only with `confirm=true` or `confirmed=true` |
| 500 | `CRM_FORM_SIDE_EFFECT_FAILED` | The write has already been performed, but the next step failed. Read the form before retrying |

### System errors

| HTTP | Code | When |
|------|-----|-------|
| 401 | `MISSING_API_KEY` | `X-Api-Key` is not passed |
| 403 | `SCOPE_DENIED` | The key does not have the `crm` scope |
| 403 | `BITRIX_ACCESS_DENIED` | The Bitrix24 user lacks permission. Original code: `error.b24Code` |
| 403 | `BITRIX_INSUFFICIENT_SCOPE` | The Bitrix24 token lacks the required scope. Original code: `error.b24Code` |
| 409 | `CRM_FORM_REST_NOT_ENABLED` | CRM form REST methods are disabled. The condition is detected from the missing-method code in `error.b24Code` |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | A write was attempted with a read-only key |
| 404 | `ENTITY_NOT_FOUND` | The form was not found |
| 422 | `BITRIX_ERROR` | Another Bitrix24 refusal, with the original code in `error.b24Code` |

Full list of common API errors — [Errors](/docs/errors).

## See also

- [Open Channels](/docs/openlines)
- [Leads](/docs/entities/leads)
- [Users](/docs/entities/users)
- [API reference](/docs/api-reference)
