
## Конвертировать лид

`POST /v1/leads/:id/convert`

Создаёт из лида сделку, контакт и компанию, связывает созданные записи между собой и закрывает лид как сконвертированный. Состав создаваемых записей задаётся телом запроса.

## Параметры

| Параметр | Тип | Обяз. | Описание |
|----------|-----|:-----:|----------|
| `id` (path) | number | да | ID лида. Список: `GET /v1/leads` |

## Поля запроса (body)

Тело запроса необязательно. Без тела и с пустым объектом `{}` применяются значения по умолчанию.

| Поле | Тип | По умолч. | Описание |
|------|-----|-----------|----------|
| `createDeal` | boolean | `true` | Создать сделку |
| `createContact` | boolean | `true` | Создать контакт |
| `createCompany` | boolean | `false` | Создать компанию по названию компании из лида |

## Примеры

### curl — личный ключ

```bash
curl -X POST https://vibecode.bitrix24.tech/v1/leads/1001207/convert \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "createDeal": true,
    "createContact": true,
    "createCompany": false
  }'
```

### curl — OAuth-приложение

```bash
curl -X POST https://vibecode.bitrix24.tech/v1/leads/1001207/convert \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "createDeal": true,
    "createContact": true,
    "createCompany": false
  }'
```

### JavaScript — личный ключ

```javascript
const res = await fetch(`https://vibecode.bitrix24.tech/v1/leads/${leadId}/convert`, {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    createDeal: true,
    createContact: true,
    createCompany: false,
  }),
})

const body = await res.json()

if (!res.ok) {
  // 422 CONVERSION_FAILED: часть записей уже создана и не откатится —
  // что именно, лежит в error.details
  throw new Error(`${body.error.code}: ${JSON.stringify(body.error.details ?? {})}`)
}

// Созданные записи читаются тем же методом, что и обычное чтение, поэтому их
// ключи приходят в общем стиле платформы
console.log('Сделка:', body.data.deal?.id, 'Контакт:', body.data.contact?.id)
```

### JavaScript — OAuth-приложение

```javascript
const res = await fetch(`https://vibecode.bitrix24.tech/v1/leads/${leadId}/convert`, {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    createDeal: true,
    createContact: true,
    createCompany: false,
  }),
})

const body = await res.json()

if (!res.ok) {
  throw new Error(`${body.error.code}: ${JSON.stringify(body.error.details ?? {})}`)
}

const { data } = body
```

## Поля ответа

| Поле | Тип | Описание |
|------|-----|----------|
| `success` | boolean | `true`, когда созданы все запрошенные записи |
| `data.lead` | object | Лид после конвертации |
| `data.deal` | object \| null | Созданная сделка. `null`, когда сделка не запрашивалась |
| `data.contact` | object \| null | Созданный контакт. `null`, когда контакт не запрашивался |
| `data.company` | object \| null | Созданная компания. `null`, когда компания не запрашивалась |

Ключи внутри `data.lead`, `data.deal`, `data.contact` и `data.company` приходят в том же виде, что и при обычном чтении записи — `id`, `title`, `stageId`, `createdTime`. Раньше этот маршрут отдавал сырой формат Битрикс24 в верхнем регистре через подчёркивание; теперь имена полей совпадают с остальными страницами раздела.

Каждая созданная запись несёт `leadId` — ссылку на лид, из которого она возникла, а сам лид получает ссылки на созданные контакт и компанию.

## Пример ответа

Показаны характерные поля. Каждая запись приходит со всем набором своих полей, включая пользовательские.

```json
{
  "success": true,
  "data": {
    "lead": {
      "id": 1001207,
      "title": "Заявка с сайта",
      "name": "Мария",
      "sourceId": "CALL",
      "statusId": "CONVERTED",
      "statusSemanticId": "S",
      "currencyId": "RUB",
      "amount": 0,
      "contactId": 2733,
      "assignedById": 1,
      "createdTime": "2026-08-25T13:47:11+03:00",
      "updatedTime": "2026-08-25T13:47:25+03:00"
    },
    "deal": {
      "id": 8345,
      "title": "Заявка с сайта",
      "stageId": "NEW",
      "categoryId": 0,
      "currencyId": "RUB",
      "amount": 0,
      "contactId": 2733,
      "companyId": null,
      "leadId": 1001207,
      "sourceId": "CALL",
      "assignedById": 1,
      "createdTime": "2026-08-25T13:47:24+03:00"
    },
    "contact": {
      "id": 2733,
      "name": "Мария",
      "lastName": null,
      "typeId": "CLIENT",
      "sourceId": "CALL",
      "leadId": 1001207,
      "companyId": null,
      "assignedById": 1,
      "createdTime": "2026-08-25T13:47:23+03:00"
    },
    "company": null
  }
}
```

## Пример ответа при ошибке

404 — лида с указанным ID не существует:

```json
{
  "success": false,
  "error": {
    "code": "ENTITY_NOT_FOUND",
    "message": "Not found"
  }
}
```

422 — контакт создался, а сделка нет. Структура ответа здесь другая: добавляется поле `error.details` с исходом каждой запрошенной операции.

```json
{
  "success": false,
  "error": {
    "code": "CONVERSION_FAILED",
    "message": "Lead conversion partially failed",
    "details": {
      "contact": { "id": 2733, "success": true },
      "deal": { "success": false, "error": "Required field is missing" }
    }
  }
}
```

Контакт `2733` остался в CRM: отката нет. Прежде чем повторять вызов, сверьте, что уже появилось в CRM, — повтор создаст второй комплект записей.

## Ошибки

| HTTP | Код | Описание |
|------|-----|----------|
| 400 | `INVALID_PARAMS` | Идентификатор лида в пути не является целым числом. Проверка идёт до обращения к Битрикс24: раньше нечисловое значение приводилось к числу на стороне Битрикс24 и конвертация выполнялась над ДРУГОЙ записью |
| 422 | `CONVERSION_FAILED` | Созданы не все запрошенные записи. Исходы отдельных операций — в поле `error.details`: по ключу на каждую запрошенную запись. Уже созданные записи не откатываются, статус лида не меняется |
| 404 | `ENTITY_NOT_FOUND` | Лида с указанным `id` не существует |
| 422 | `BITRIX_ERROR` | Битрикс24 отклонил чтение лида или его закрытие. Отказ на создании сделки, контакта или компании сюда не попадает — он приходит как `CONVERSION_FAILED`. Текст в `message` приходит от Битрикс24 дословно, поля `error.details` в этом ответе нет |
| 403 | `BITRIX_ACCESS_DENIED` | Битрикс24 отказал в доступе к лиду |
| 403 | `SCOPE_DENIED` | API-ключу не хватает скоупа `crm` |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | Ключ переведён в режим только для чтения, а конвертация создаёт записи |
| 401 | `TOKEN_MISSING` | У API-ключа нет действующих токенов Битрикс24 |
| 429 | `RATE_LIMITED` | Превышен лимит запросов к порталу |

Полный список общих ошибок API — [Ошибки](/docs/errors).

## Известные особенности

- **Повторный вызов создаёт второй комплект записей.** Эндпоинт не проверяет, был ли лид сконвертирован раньше, поэтому повтор после обрыва связи задваивает данные в CRM. Признак уже сконвертированного лида — статус `CONVERTED`. Перед повтором запросите лид через [`GET /v1/leads/:id`](/docs/entities/leads/get) — там статус приходит в поле `stageId`.
- **Отката при частичном отказе нет.** Сделка, контакт и компания создаются отдельными записями одна за другой. Если одна из них не создалась, ранее созданные остаются в CRM, а статус лида не меняется. Перед повторным вызовом сверьте, что уже появилось в CRM, иначе повтор добавит дубли к уже созданному.
- **Вернуться к camelCase можно перечитыванием записи.** Возьмите `ID` созданной записи и запросите её через [`GET /v1/deals/:id`](/docs/entities/deals/get) или [`GET /v1/contacts/:id`](/docs/entities/contacts/get) — там поля приходят в camelCase.
- **В создаваемые записи переносится ограниченный набор полей.** Контакт получает имя, фамилию, отчество, источник и ответственного. Компания — название компании из лида и ответственного. Сделка — название, сумму, валюту, источник и ответственного. Остальные поля лида, включая пользовательские, не копируются, поэтому недостающие значения дописывайте отдельным вызовом [`PATCH /v1/deals/:id`](/docs/entities/deals/update).
- **Товарные позиции лида копируются в созданную сделку.** Когда перенос позиций не удался, сделка остаётся созданной, а конвертация — успешной. Состав товаров сверяйте вызовом [`GET /v1/deals/:id/products`](/docs/entities/deals/products-get).
- **Созданные записи несут обратную ссылку на исходный лид.** У сделки, контакта и компании проставляется `leadId`, а сам лид получает `contactId` и `companyId` — так что сделку можно найти по лиду, из которого она возникла, фильтром по `leadId`, и хранить соответствие на своей стороне больше не нужно.

## Смотрите также

- [Лиды](/docs/entities/leads)
- [Получить лид](/docs/entities/leads/get)
- [Обновить лид](/docs/entities/leads/update)
- [Сделки](/docs/entities/deals)
- [Контакты](/docs/entities/contacts)
- [Компании](/docs/entities/companies)
