
## Пригласить сотрудника

`POST /v1/users/invite`

Создаёт нового сотрудника или приглашает внешнего пользователя на портал. Принимает поля в `camelCase` и `UPPER_SNAKE_CASE`, проставляет разумные значения по умолчанию и проверяет email до вызова Битрикс24 — возвращая понятные коды ошибок (`EMAIL_REQUIRED`, `EMAIL_INVALID`, `SONET_GROUP_ID_REQUIRED`) вместо общего `wrong_email`.

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

| Параметр | Тип | Обяз. | Описание |
|----------|-----|:-----:|---------|
| `email` | string | да | Email — должен быть уникальным среди всех сотрудников портала. Базовая синтаксическая проверка происходит на стороне Вайбкод |
| `name` | string | нет | Имя |
| `lastName` | string | нет | Фамилия |
| `secondName` | string | нет | Отчество |
| `workPosition` | string | нет | Должность |
| `workPhone` | string | нет | Рабочий телефон |
| `workCompany` | string | нет | Название компании |
| `personalPhone` | string | нет | Личный телефон |
| `personalMobile` | string | нет | Мобильный телефон |
| `personalBirthday` | string | нет | Дата рождения (ISO 8601) |
| `personalGender` | string | нет | Пол: `M` — мужской, `F` — женский |
| `personalCity` | string | нет | Город |
| `personalPhoto` | [string, string] | нет | Фото для записи: пара `[имяФайла, base64Содержимое]`. URL из ответов чтения здесь не принимается |
| `xmlId` | string | нет | Внешний идентификатор сотрудника для интеграций |
| `timeZone` | string | нет | Часовой пояс, например `Europe/Kaliningrad` |
| `personalWww` | string | нет | Адрес личного сайта |
| `personalProfession` | string | нет | Профессия |
| `title` | string | нет | Обращение или звание |
| `personalIcq` | string | нет | Номер ICQ |
| `personalFax` | string | нет | Личный факс |
| `personalPager` | string | нет | Номер пейджера |
| `personalStreet` | string | нет | Улица в адресе проживания |
| `departmentId` | number[] | нет | Массив ID отделов. По умолчанию `[1]` (корневой отдел) для штатных сотрудников. Список: `GET /v1/departments` |
| `extranet` | string | нет | `"Y"` для приглашения внешнего пользователя. В этом случае `departmentId` игнорируется и обязателен `sonetGroupId` |
| `sonetGroupId` | number[] | условно | Массив ID рабочих групп — обязателен при `extranet: "Y"`. Список: [`GET /v1/workgroups`](/docs/entities/workgroups) |
| `active` | boolean | нет | Признак активности (по умолчанию `true`) |

## Примеры

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

```bash
curl -X POST "https://vibecode.bitrix24.tech/v1/users/invite" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "ivan.petrov@example.com",
    "name": "Иван",
    "lastName": "Петров",
    "workPosition": "Менеджер"
  }'
```

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

```bash
curl -X POST "https://vibecode.bitrix24.tech/v1/users/invite" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "ivan.petrov@example.com",
    "name": "Иван",
    "lastName": "Петров",
    "workPosition": "Менеджер"
  }'
```

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

```javascript
const res = await fetch('https://vibecode.bitrix24.tech/v1/users/invite', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    email: 'ivan.petrov@example.com',
    name: 'Иван',
    lastName: 'Петров',
    workPosition: 'Менеджер',
  }),
})

const { success, data } = await res.json()
console.log('Создан сотрудник ID:', data.id)
```

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

```javascript
const res = await fetch('https://vibecode.bitrix24.tech/v1/users/invite', {
  method: 'POST',
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    email: 'ivan.petrov@example.com',
    name: 'Иван',
    lastName: 'Петров',
  }),
})

const { success, data } = await res.json()
```

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

| Поле | Тип | Описание |
|------|-----|---------|
| `success` | boolean | Всегда `true` при успехе |
| `data.id` | number | ID созданного сотрудника |
| `data.user` | object | Полная запись только что созданного сотрудника — те же поля, что у [`GET /v1/users/:id`](/docs/entities/users/get) |

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

```json
{
  "success": true,
  "data": {
    "id": 1331,
    "user": {
      "id": 1331,
      "xmlId": "74668002",
      "active": true,
      "name": "Иван",
      "lastName": "Петров",
      "email": "ivan.petrov@example.com",
      "lastLogin": null,
      "dateRegister": "2026-05-06T00:00:00.000Z",
      "isOnline": false,
      "timestampX": {},
      "personalGender": null,
      "departmentId": [1],
      "workPosition": "Менеджер",
      "userType": "employee"
    }
  }
}
```

HTTP-статус ответа — `201 Created`.

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

400 — email не передан:

```json
{
  "success": false,
  "error": {
    "code": "EMAIL_REQUIRED",
    "message": "EMAIL (or `email`) is required to invite a user."
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|---------|
| 400 | `EMAIL_REQUIRED` | В теле запроса нет `email` (или `EMAIL`) |
| 400 | `EMAIL_INVALID` | Email не прошёл синтаксическую проверку Вайбкод |
| 400 | `PERSONAL_PHOTO_INVALID` | `personalPhoto` передан не как пара `[имяФайла, base64Содержимое]` |
| 400 | `SONET_GROUP_ID_REQUIRED` | При `extranet: "Y"` не передан `sonetGroupId` |
| 400 | `BITRIX_ERROR` (`wrong_email`) | Битрикс24 отклонил создание: email уже занят, домен запрещён политикой портала, или другая ошибка email |
| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |
| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` |

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

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

**Зачем дефолт `departmentId: [1]`.** Без `UF_DEPARTMENT` Битрикс24 возвращает обобщённый `wrong_email` без указания причины — отсутствие отдела у штатного сотрудника одна из самых частых ловушек. Подстановка корневого отдела `[1]` устраняет её для типового случая «приглашаем сотрудника, конкретный отдел неизвестен». Если структура отделов важна — передавайте `departmentId` явно.

**Уникальность email на портале.** Email проверяется среди всех сотрудников включая ранее деактивированных — при дубле Битрикс24 отдаст `BITRIX_ERROR: wrong_email`. Перед приглашением — поиск через `GET /v1/users?filter[EMAIL]=ivan.petrov@example.com`. Если найден деактивированный, верните его в строй через [`PATCH /v1/users/:id { active: true }`](/docs/entities/users/update) — это сохранит историю и связи, в отличие от создания дубля.

**Best-effort повторное чтение.** После успешного создания обёртка делает повторное чтение записи и кладёт её в `data.user`. Если вспомогательный вызов упал, `data.id` всё равно вернётся — сотрудник уже создан, повторное обращение [`GET /v1/users/:id`](/docs/entities/users/get) подгрузит запись.

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

- [Создать сотрудника](/docs/entities/users/create)
- [Список сотрудников](/docs/entities/users/list)
- [Обновить сотрудника](/docs/entities/users/update)
- [Отделы](/docs/entities/departments)
- [Лимиты и оптимизация](/docs/optimization)
