# Импорт записей CRM

Перенос уже существующих данных в CRM: до 100 записей за запрос, с сохранением автора и дат из внешней системы.

**Импорт не запускает автоматизацию.** Роботы, триггеры и бизнес-процессы, настроенные на создание элемента, на импортированных записях не срабатывают — это свойство самой операции в Битрикс24, а не наш параметр. Если вам нужно, чтобы автоматизация отработала, создавайте записи обычным способом — `POST /v1/{entity}`.

`POST /v1/{entity}/import`

**Скоуп:** `crm` | **Базовый URL:** `https://vibecode.bitrix24.tech/v1` | **Авторизация:** `X-Api-Key` (APP-ключ)

## Для каких объектов доступен

| Путь | Объект |
|------|--------|
| `POST /v1/leads/import` | Лиды |
| `POST /v1/deals/import` | Сделки |
| `POST /v1/contacts/import` | Контакты |
| `POST /v1/companies/import` | Компании |
| `POST /v1/quotes/import` | Предложения |
| `POST /v1/invoices/import` | Счета |
| `POST /v1/items/{entityTypeId}/import` | Элементы смарт-процессов |

У остальных сущностей такого маршрута нет — Битрикс24 умеет импортировать только объекты CRM.

## Чем импорт отличается от создания

| | `POST /v1/{entity}` | `POST /v1/{entity}/import` |
|---|---|---|
| Право в Битрикс24 | право на добавление | **право на импорт** — отдельное, выдаёт администратор портала |
| Роботы и бизнес-процессы | запускаются | **не запускаются** |
| Автор и даты записи | проставляет Битрикс24 | можно передать свои (см. ниже) |
| За один запрос | одна запись | до 100 записей |
| Ответ | созданная запись целиком | исход по каждой записи |

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

| Поле | Тип | Обяз. | Описание |
|------|-----|:---:|---------|
| `items` | array | ★ | Массив записей, от 1 до 100. Поля каждой записи — те же, что у `POST /v1/{entity}`, плюс служебные поля ниже. Поля записи передаются плоско: объект `fields` при отсутствии этого поля в схеме отклоняет весь импорт с `400 IMPORT_ITEM_VALIDATION`, индексом записи и причиной `NESTED_FIELDS_ENVELOPE`. |

```bash
curl -X POST 'https://vibecode.bitrix24.tech/v1/leads/import' \
  -H 'X-Api-Key: YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "items": [
      {
        "title": "Website request",
        "name": "Jane",
        "lastName": "Doe",
        "phone": "+15551234567",
        "email": "jane@example.com",
        "assignedById": 31,
        "createdBy": 11
      }
    ]
  }'
```

## Служебные поля

Только на импорте принимаются шесть полей, которые Битрикс24 обычно заполняет сам:

| Поле | Что задаёт |
|------|-----------|
| `createdBy` | Кто создал запись |
| `createdTime` | Когда запись создана |
| `updatedBy` | Кто изменил запись |
| `updatedTime` | Когда запись изменена |
| `movedBy` | Кто перевёл запись на текущую стадию |
| `movedTime` | Когда стадия изменилась |

Проставить их может **только администратор портала**. Обычному пользователю Битрикс24 ответит по такой записи ошибкой `CRM_FIELD_ERROR_VALUE_NOT_VALID` — остальные записи пакета при этом создадутся.

Передавайте существующего сотрудника. Битрикс24 не проверяет идентификатор на существование и запишет любое число — в карточке будет призрачный автор. Записью при этом можно управлять как обычно.

Набор доступных полей отличается по объектам: у сделок и счетов есть все шесть, у лидов — автор и даты создания и изменения. Точный перечень для конкретной сущности возвращает `GET /v1/{entity}/fields` — служебные поля помечены там `"importable": true` рядом с `"readonly": true`. Тот же признак доступен без сессии в `GET /v1/guide`, в `data.entities[].fieldsDetailed`.

## Ограничение на даты

У `createdTime` есть окно, которое задаёт Битрикс24, и обойти его нельзя:

- дата не может быть **позже текущего момента**;
- дата не может быть **раньше, чем у самой свежей уже существующей записи этого объекта**.

То есть перенести историю целиком получится в пустую CRM или в такую, где все записи старше переносимых. В наполненную CRM «подложить» записи задним числом Битрикс24 не даст — ответит `CRM_FIELD_ERROR_VALUE_NOT_VALID` с пояснением. Каждая успешно импортированная запись поднимает нижнюю границу окна, поэтому переносите пачки от старых к новым.

`updatedTime` должен быть не раньше `createdTime`, а `movedTime` — попадать между ними.

Если история не нужна, просто не передавайте даты: автора можно проставить и без них.

## Ответ

Ответ приходит со статусом `200` даже когда часть записей не прошла — импорт не транзакционен, и результат нужно читать по каждой записи.

```json
{
  "success": true,
  "data": {
    "results": [
      { "index": 0, "success": true, "id": 147 },
      {
        "index": 1,
        "success": false,
        "error": "CRM_FIELD_ERROR_VALUE_NOT_VALID",
        "message": "Значение поля \"Когда создан\" не может быть в будущем времени"
      }
    ],
    "summary": { "total": 2, "succeeded": 1, "failed": 1 }
  }
}
```

| Поле | Описание |
|------|----------|
| `results[].index` | Позиция записи в отправленном массиве `items`. Длина `results` всегда равна длине `items`. |
| `results[].success` | Создана ли запись. |
| `results[].id` | Идентификатор созданной записи. Приходит при `success: true` — и при отказах `STAGE_NOT_APPLIED` / `AMOUNT_NOT_APPLIED`, потому что запись при них уже создана. |
| `results[].error` | Код ошибки Битрикс24 — либо код проверки платформы: [`STAGE_NOT_APPLIED`](/docs/errors), когда переданная стадия или воронка не применилась и запись создана на стадии по умолчанию (обычно несуществующее значение), и [`AMOUNT_NOT_APPLIED`](/docs/errors), когда явно запрошенный ручной режим суммы у элемента смарт-процесса не сохранился (тип без товарной части). |
| `results[].message` | Пояснение к ошибке. У кодов проверки платформы называет запрошенное и фактическое значение. |
| `results[].details` | Только у кодов проверки платформы: `unappliedFields` — что не применилось, `currentValues` — что стоит в записи. |
| `summary` | Сводка: `total`, `succeeded`, `failed`. |

**Всегда проверяйте `summary.failed`.** Статус `200` означает «запрос обработан», а не «все записи созданы».

**Стадия и ручная сумма сверяются после импорта.** Битрикс24 принимает импорт с несуществующей стадией и молча кладёт запись на стадию по умолчанию; ручной режим суммы у типа без товарной части так же молча теряется. Поэтому после всех пачек платформа перечитывает созданные записи — один раз на каждые 50, страницей списка — и помечает те, у кого стадия, воронка или явно запрошенный `isManualOpportunity: true` не применились, кодом `STAGE_NOT_APPLIED` / `AMOUNT_NOT_APPLIED` — с сохранённым `id`: запись существует, повторять её нельзя, исправьте значение через `PATCH` или `/move`. Перечитываются только записи, у которых была стадия, воронка или явный ручной режим суммы; импорт без них стоит ровно столько, сколько раньше. Импорт не запускает правила автоматизации, поэтому перечитанная запись — итог самого импорта, а не робота. Если перечитать не удалось, строки остаются такими, как их вернул Битрикс24. Пустая стадия (`null`, `""`) не сверяется — запись ляжет на стадию по умолчанию. Сумма без явного `isManualOpportunity: true` не проверяется. Лид, который портал в простом режиме CRM сам перевёл в «сконвертирован», за неприменённую стадию не считается.

Повторный импорт создаст дубли — идемпотентности у операции нет. Если повторы возможны, записывайте идентификатор записи из внешней системы в поля `originatorId` и `originId`: по ним потом можно найти уже перенесённое.

## Ошибки

| HTTP | Код | Когда |
|------|-----|-------|
| 400 | `IMPORT_ITEM_VALIDATION` | `items` отсутствует, пуст или не массив; элемент не объект либо пуст; в элементе поле, недоступное на запись, включая объект `fields` при отсутствии такого поля в схеме. Текст называет позицию и причину `NESTED_FIELDS_ENVELOPE`: `Item at index N: …` |
| 400 | `IMPORT_LIMIT_EXCEEDED` | Больше 100 записей в запросе. Разбейте пакет и отправьте части по порядку. |
| 400 | `INVALID_DYNAMIC_PARAM` | Некорректный `entityTypeId` в пути `/v1/items/{entityTypeId}/import`, либо у этого типа есть свой маршрут (например для сделок — `/v1/deals/import`). |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | Ключ работает в режиме «только чтение». |
| 403 | `SCOPE_DENIED` | У ключа нет скоупа `crm`. |
| 429 | `RATE_LIMITED` | Слишком часто. Импорт ограничен по темпу на портал, чтобы массовая заливка не блокировала другие интеграции. Повторите через время из заголовка `Retry-After`. |
| 404 | — | У этой сущности импорта нет. |

Ошибки по отдельным записям приходят внутри `200`, в `results[]` — там коды самого Битрикс24 и два кода проверки платформы, `STAGE_NOT_APPLIED` и `AMOUNT_NOT_APPLIED` (см. выше).

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

## Что учесть при переносе базы

- **Один поток.** Внутри одного запроса порядок гарантирован, между параллельными запросами — нет, а Битрикс24 требует неубывающих дат создания. Импортируйте последовательно.
- **Скорость.** Сто записей за запрос — примерно 12–15 секунд; лимит темпа даёт около тысячи записей в минуту на портал. Для базы в десятки тысяч записей закладывайте время.
- **Сбой посреди пакета.** Если связь с Битрикс24 оборвалась после того, как часть записей уже создана, ответ всё равно придёт со статусом `200`: созданные будут с идентификаторами, оставшиеся — помечены ошибкой. Это единственный источник знания о том, что успело пройти, — перед повтором сверьтесь с ним.
- **Телефон и почта.** Передавайте как обычно (`"phone": "+15551234567"` или массивом объектов) — приведение к формату, который принимает импорт, платформа делает сама.

## Смежные страницы

- [Создание записи](./entities/leads/create.md) — обычный путь, с автоматизацией
- [Пакетные вызовы](./batch.md) — до 50 операций над разными сущностями в одном запросе
- [Поля лида](./entities/leads/fields.md) — какие поля доступны и какие из них служебные
