# CRM field values and primary contact

Change one value without replacing the whole list, or choose an existing bound contact as primary.

Bitrix24 API: `crm.<entity>.addfieldvalue`, `crm.<entity>.deletefieldvalue`, `crm.<entity>.setprimarycontact`
Scope: `crm`

> These operations require the `crm-rest-v3` flag and a Bitrix24 update after `crm 26.2200.0` with `RestV3CrudDeal` enabled. Until then, calls return `422 METHOD_NOT_YET_AVAILABLE` with `error.release`.

## Operations

- [Add one value](./crm-field-values/add.md) — `POST /v1/deals/:id/fields/:field/values`
- [Remove one value](./crm-field-values/delete.md) — `DELETE /v1/deals/:id/fields/:field/values`
- [Set primary contact](./crm-field-values/primary-contact.md) — `PUT /v1/deals/:id/primary-contact`

## Resources

| Resource | Value changes | Primary contact |
|---|---|---|
| `/v1/deals` | POST / DELETE | PUT |
| `/v1/leads` | POST / DELETE | PUT |
| `/v1/contacts` | POST / DELETE | — |
| `/v1/companies` | POST / DELETE | — |
| `/v1/quotes` | POST / DELETE | PUT |
| `/v1/invoices` | POST / DELETE | PUT |
| `/v1/items/:entityTypeId` | POST / DELETE | PUT |

## Key fields

The `:field` path segment uses native REST v3 spelling.

| Field | Description |
|---|---|
| `phone`, `email`, `web`, `im` | Multifields. The value is a `{valueTypeId,value}` object. |
| `contactsId` | Contact binding. The value is an ID from [List contacts](/docs/entities/contacts/list). |
| `companiesId` | Company binding. The value is an ID from [List companies](/docs/entities/companies/list). |
| `observersId` | Observer. The value is an ID from [List employees](/docs/entities/users/list). |
| `UF_CRM_*` | Custom field by its exact name. The value is one value of its native type. To add a file, pass a file ID or an upload object; to delete one, pass the stored value. |
| `contactId` | Body field of the primary-contact operation: the ID of an already bound contact from [List contacts](/docs/entities/contacts/list). |

Bitrix24 decides whether the field and value are supported.

## Before you start

All operations require a READWRITE key. Record IDs come from the corresponding list resource; contact IDs come from [List contacts](/docs/entities/contacts/list), and smart-process type IDs from [List smart process types](/docs/entities/smart-processes/list).

For your own company, use the `companies` resource with `?isMyCompany=true`. The default is `false`. This selects own-company permissions without changing the record type. For invoices and smart processes, the primary-contact operation is available only when contact bindings are supported.

A successful operation returns `204 No Content` with no body. After a timeout or ambiguous failure, read the record before retrying.

## Typical scenario

1. Find the record in the list of its resource, for example [List deals](/docs/entities/deals/list). For a smart process, take `entityTypeId` from [List smart process types](/docs/entities/smart-processes/list).
2. Add a value: [`POST /v1/deals/:id/fields/:field/values`](./crm-field-values/add.md).
3. Remove the previous value by passing the stored value: [`DELETE /v1/deals/:id/fields/:field/values`](./crm-field-values/delete.md).
4. Choose the primary contact among the bound ones: [`PUT /v1/deals/:id/primary-contact`](./crm-field-values/primary-contact.md).
5. Check the result by reading the record, for example [`GET /v1/deals/:id`](/docs/entities/deals/get).

## Limits

| Limit | Value |
|-------|----------|
| Values per call | One. The body contains only `value`; for the primary contact, only `contactId` |
| Query string parameters | Only `isMyCompany`, and only on the `companies` resource. Any other parameter is rejected with `400 UNKNOWN_FILTER_FIELD` |
| Rate limit | shared across the Vibecode API — see [Limits and optimization](/docs/optimization) |

## See also

- [CRM](/docs/entity-api)
- [Errors](/docs/errors)
