# Контакты сделки

Управление связями сделки с контактами (many-to-many). Поле `contactIds` в самой сделке доступно только для чтения — `PATCH /v1/deals/:id` его не меняет. Чтобы привязать, заменить или отвязать контакты, используйте эндпоинты ниже. Прочитать список контактов вместе со сделкой можно через `GET /v1/deals/:id?include=contact` (см. «Включение связанных сущностей»).

Требуется scope `crm`.

## Поля связи

| Поле | Тип | Описание |
|----------|-----|---------|
| `contactId` | number | ID контакта. Каталог: `GET /v1/contacts` |
| `isPrimary` | boolean | Основной контакт сделки. Если ни один не помечен, основным станет первый |
| `sort` | number | Порядок сортировки |
| `roleId` | number | ID роли контакта (если используется) |

## Получить контакты сделки

`GET /v1/deals/:id/contacts`

Возвращает массив привязанных контактов.

```bash
curl "https://vibecode.bitrix24.tech/v1/deals/741/contacts" \
  -H "X-Api-Key: YOUR_API_KEY"
```

Ответ:

```json
{
  "success": true,
  "data": [
    { "contactId": 9, "sort": 10, "isPrimary": true, "roleId": 0 },
    { "contactId": 17, "sort": 20, "isPrimary": false, "roleId": 0 }
  ]
}
```

## Добавить один контакт

`POST /v1/deals/:id/contacts`

Привязывает один контакт к сделке, не затрагивая уже привязанные.

| Параметр | Тип | Обяз. | Описание |
|----------|-----|:-----:|---------|
| `contactId` | number | да | ID контакта |
| `isPrimary` | boolean | нет | Сделать основным |
| `sort` | number | нет | Порядок сортировки |

```bash
curl -X POST "https://vibecode.bitrix24.tech/v1/deals/741/contacts" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "contactId": 9, "isPrimary": true, "sort": 10 }'
```

Возвращает обновлённый список контактов сделки (как в `GET`).

## Заменить весь список контактов

`PUT /v1/deals/:id/contacts`

Полностью заменяет список контактов сделки. Контакты, не вошедшие в `items`, отвязываются. Передайте `"items": []`, чтобы отвязать все.

| Параметр | Тип | Обяз. | Описание |
|----------|-----|:-----:|---------|
| `items` | array | да | Массив контактов (пустой массив отвязывает все) |
| `items[].contactId` | number | да | ID контакта |
| `items[].isPrimary` | boolean | нет | Основной контакт |
| `items[].sort` | number | нет | Порядок сортировки |

```bash
curl -X PUT "https://vibecode.bitrix24.tech/v1/deals/741/contacts" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      { "contactId": 16530, "isPrimary": true, "sort": 10 },
      { "contactId": 16532, "isPrimary": false, "sort": 20 }
    ]
  }'
```

Возвращает обновлённый список контактов сделки (как в `GET`).

## Удалить один контакт

`DELETE /v1/deals/:id/contacts/:contactId`

Отвязывает один контакт. Если удаляется основной, основным становится первый из оставшихся.

```bash
curl -X DELETE "https://vibecode.bitrix24.tech/v1/deals/741/contacts/16530" \
  -H "X-Api-Key: YOUR_API_KEY"
```

Возвращает `204 No Content`.

## Ошибки

| Код | Когда |
|-----|-------|
| `INVALID_PARAMS` | В `PUT` поле `items` не массив, либо элемент без `contactId` |
| `SCOPE_DENIED` | У ключа нет scope `crm` |
| `WRITE_BLOCKED_READONLY_KEY` | Ключ в режиме READONLY — записи (`POST`/`PUT`/`DELETE`) запрещены |
