[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"docs-entities\u002Fusers":3,"docs-tabs-entities\u002Fusers":6},{"content":4,"lastmod":5},"\n# Пользователи\n\nУправление сотрудниками портала: список, получение по ID, приглашение нового, обновление, деактивация. Сущность хранит контактные данные, должность, отдел и пользовательские поля (UF) сотрудника.\n\nБитрикс24 API: `user.*`\nСкоуп: `user`\n\n## Операции\n\n- [Создать сотрудника](.\u002Fusers\u002Fcreate.md) — `POST \u002Fv1\u002Fusers`\n- [Пригласить сотрудника](.\u002Fusers\u002Finvite.md) — `POST \u002Fv1\u002Fusers\u002Finvite`\n- [Список сотрудников](.\u002Fusers\u002Flist.md) — `GET \u002Fv1\u002Fusers`\n- [Получить сотрудника](.\u002Fusers\u002Fget.md) — `GET \u002Fv1\u002Fusers\u002F:id`\n- [Обновить сотрудника](.\u002Fusers\u002Fupdate.md) — `PATCH \u002Fv1\u002Fusers\u002F:id`\n- [Деактивировать сотрудника](.\u002Fusers\u002Fdelete.md) — `DELETE \u002Fv1\u002Fusers\u002F:id`\n- [Поиск сотрудников](.\u002Fusers\u002Fsearch.md) — `POST \u002Fv1\u002Fusers\u002Fsearch`\n- [Поля сотрудника](.\u002Fusers\u002Ffields.md) — `GET \u002Fv1\u002Fusers\u002Ffields`\n- [Агрегация сотрудников](.\u002Fusers\u002Faggregate.md) — `POST \u002Fv1\u002Fusers\u002Faggregate`\n\n## Ключевые поля\n\n| Поле | Описание |\n|------|---------|\n| `id` | Идентификатор сотрудника |\n| `name` \u002F `lastName` \u002F `secondName` | Имя, фамилия, отчество |\n| `email` | Email — обязательно при создании, должен быть уникальным среди всех сотрудников портала |\n| `active` | Признак активности: `true` — работает, `false` — деактивирован |\n| `workPosition` | Должность |\n| `departmentId` | Массив ID отделов сотрудника. Список: `GET \u002Fv1\u002Fdepartments` |\n| `personalPhone` \u002F `personalMobile` \u002F `workPhone` | Телефоны |\n| `isAdmin` | Признак администратора портала (только чтение). Наполняется **только в `GET \u002Fv1\u002Fusers\u002Fme`**, трёхзначно: `true` — админ, `false` — не админ, `null` — определить не удалось (временный сбой; профиль всё равно возвращается, это не ошибка) — пригоден для серверной проверки прав. **В `GET \u002Fv1\u002Fusers\u002F:id` и списке `GET \u002Fv1\u002Fusers` поле недоступно**: `user.get` его не возвращает (`data.isAdmin` = `undefined`), вердикт отдаётся только для текущего пользователя сессии. |\n\nПолный список полей — [`GET \u002Fv1\u002Fusers\u002Ffields`](\u002Fdocs\u002Fentities\u002Fusers\u002Ffields).\n\n## Что нужно знать перед работой\n\n1. **Создание требует email.** Поле `email` обязательное и должно быть уникальным для всего портала. Дубль вернёт `BITRIX_ERROR: wrong_email` без явного указания причины — этот код Битрикс24 использует для нескольких разных кейсов (см. ниже).\n2. **Два эндпоинта для создания.** [`POST \u002Fv1\u002Fusers`](\u002Fdocs\u002Fentities\u002Fusers\u002Fcreate) — обычная entity-форма, проксирует ошибки Битрикс24 как есть. [`POST \u002Fv1\u002Fusers\u002Finvite`](\u002Fdocs\u002Fentities\u002Fusers\u002Finvite) — обёртка с предзаполнением `departmentId: [1]` для штатных сотрудников и явной валидацией email на стороне Вайбкод (`EMAIL_REQUIRED`, `EMAIL_INVALID`). Для интеграций предпочтительнее `\u002Finvite` — у него понятные коды ошибок.\n3. **PATCH и DELETE требуют прав администратора портала.** Битрикс24 применяет обновление сотрудника только если у владельца ключа есть админские права на портале. Без них Битрикс24 возвращает `result: false`, Вайбкод оборачивает это в `403 UPDATE_FAILED` с подсказкой в поле `hint`.\n4. **`DELETE \u002Fv1\u002Fusers\u002F:id` — это деактивация.** Эндпоинт снимает у сотрудника доступ к порталу, но сохраняет всю запись и её связи (ответственный за сделки, автор комментариев, участник чатов). Под капотом маппится на обновление поля активности (`active: false`), в ответе явный маркер `deactivated: true`. Восстановить доступ — `PATCH \u002Fv1\u002Fusers\u002F:id { active: true }`. Данные не теряются.\n5. **Поля только для чтения.** `id`, `isOnline`, `isAdmin`, `lastLogin`, `dateRegister`, `lastActivityDate`, `userType`, `timestampX` заполняются системой. Попытка передать их в `PATCH \u002Fv1\u002Fusers\u002F:id` отклоняется заранее с `400 READONLY_FIELD` — вызов Битрикс24 не происходит.\n6. **`WORK_*` \u002F `PERSONAL_*` обычно не приходят, а пустые поля Битрикс24 опускает.** Стандартные заполненные поля (`name`, `email`, `active`, `departmentId`, `timeZone`, `userType` и др.) — `camelCase`. Поля `WORK_COMPANY`, `WORK_DEPARTMENT`, `PERSONAL_STATE`, `PERSONAL_ZIP` и аналогичные на практике в ответе **отсутствуют** (Битрикс24 не возвращает незаполненные поля); если такое поле всё же приходит — оно сохраняет исходное имя `UPPER_SNAKE_CASE` (не камелкейсится). То есть ключа может **не быть вовсе** — не полагайтесь на его присутствие.\n7. **«Пусто» в datetime-полях закодировано тремя способами.** `timestampX` и `lastActivityDate` (объявлены `datetime`) приходят **пустым объектом `{}`**, а не строкой\u002F`null` (`new Date(u.timestampX)` → `Invalid Date`; `if (u.lastActivityDate)` — **истинно** даже без активности). `lastActivityDate` к тому же может **отсутствовать** как ключ. `lastLogin` отдаёт `null`, когда входа не было. `dateRegister` — ISO-строка всегда (полночь UTC). Проверяйте «активность была» сравнением типа (`typeof x === 'string'`), а не truthy-проверкой.\n8. **Внешние сотрудники (extranet).** При создании пользователя экстранета `EXTRANET: \"Y\"` обязательное поле `SONET_GROUP_ID` (массив ID рабочих групп) вместо `departmentId`. `\u002Finvite` явно отдаёт `400 SONET_GROUP_ID_REQUIRED`, если оба не переданы.\n\n## Типичный сценарий\n\n1. Найти сотрудника по части имени или email: [`GET \u002Fv1\u002Fusers?filter[NAME]=Иван`](\u002Fdocs\u002Fentities\u002Fusers\u002Flist).\n2. Получить полные данные одного: [`GET \u002Fv1\u002Fusers\u002F:id`](\u002Fdocs\u002Fentities\u002Fusers\u002Fget).\n3. Пригласить нового через Вайбкод-обёртку: [`POST \u002Fv1\u002Fusers\u002Finvite`](\u002Fdocs\u002Fentities\u002Fusers\u002Finvite).\n4. Обновить должность или отдел: [`PATCH \u002Fv1\u002Fusers\u002F:id`](\u002Fdocs\u002Fentities\u002Fusers\u002Fupdate).\n5. Если сотрудник уволился — деактивировать: [`DELETE \u002Fv1\u002Fusers\u002F:id`](\u002Fdocs\u002Fentities\u002Fusers\u002Fdelete). Восстановить — `PATCH \u002Fv1\u002Fusers\u002F:id { active: true }`.\n\n## Лимиты\n\n| Лимит | Значение |\n|-------|----------|\n| Максимум записей на запрос | 5000 (`limit ≤ 5000`) |\n| Авто-пагинация | включается при `limit > 50` |\n| `offset` на больших выборках | рекомендуется `limit ≤ 500` при `offset ≥ 2500` |\n| Batch-запросы | до 50 операций в [`POST \u002Fv1\u002Fbatch`](\u002Fdocs\u002Fbatch) |\n| Rate limit | общий для Vibe API — см. [Лимиты и оптимизация](\u002Fdocs\u002Foptimization) |\n\n## Смотрите также\n\n- [Отделы](\u002Fdocs\u002Fentities\u002Fdepartments) — `departmentId` берётся из `GET \u002Fv1\u002Fdepartments`\n- [Entity API](\u002Fdocs\u002Fentity-api) — общие принципы работы с сущностями\n- [Синтаксис фильтрации](\u002Fdocs\u002Ffiltering)\n- [Batch](\u002Fdocs\u002Fbatch) — массовые операции\n- [Справочник сущностей](\u002Fdocs\u002Fentities-index)\n","2026-07-07",{"users\u002Fcreate.md":7,"users\u002Finvite.md":8,"users\u002Flist.md":9,"users\u002Fget.md":10,"users\u002Fupdate.md":11,"users\u002Fdelete.md":12,"users\u002Fsearch.md":13,"users\u002Ffields.md":14,"users\u002Faggregate.md":15},"\n## Создать сотрудника\n\n`POST \u002Fv1\u002Fusers`\n\nСоздаёт нового сотрудника на портале. Минимальное обязательное поле — `email`. Возвращает ID и полную запись только что созданного сотрудника.\n\n> Для интеграций с пользовательским вводом удобнее [`POST \u002Fv1\u002Fusers\u002Finvite`](\u002Fdocs\u002Fentities\u002Fusers\u002Finvite): он валидирует email на стороне Вайбкод (`EMAIL_REQUIRED`, `EMAIL_INVALID`) и автоматически проставляет `departmentId: [1]` для штатных сотрудников. Этот эндпоинт — низкоуровневая форма, ошибки прокидываются от Битрикс24 как есть.\n\n## Поля запроса (body)\n\n| Параметр | Тип | Обяз. | Описание |\n|----------|-----|:-----:|---------|\n| `email` | string | да | Email — должен быть уникальным среди всех сотрудников портала |\n| `name` | string | нет | Имя |\n| `lastName` | string | нет | Фамилия |\n| `secondName` | string | нет | Отчество |\n| `workPosition` | string | нет | Должность |\n| `workPhone` | string | нет | Рабочий телефон |\n| `personalPhone` | string | нет | Личный телефон |\n| `personalMobile` | string | нет | Мобильный телефон |\n| `personalBirthday` | string | нет | Дата рождения (ISO 8601) |\n| `personalGender` | string | нет | Пол: `M` — мужской, `F` — женский |\n| `personalCity` | string | нет | Город |\n| `departmentId` | number[] | условно | Массив ID отделов. Для штатных сотрудников **обязателен** — без него Битрикс24 вернёт `wrong_email`. Для экстранета (`EXTRANET: \"Y\"`) не используется |\n| `xmlId` | string | нет | Внешний идентификатор |\n| `EXTRANET` | string | нет | `\"Y\"` для пользователя экстранета. Тогда вместо `departmentId` нужен `SONET_GROUP_ID` (массив ID рабочих групп) |\n| `SONET_GROUP_ID` | number[] | условно | Массив ID рабочих групп — обязателен при `EXTRANET: \"Y\"`. Список: [`GET \u002Fv1\u002Fworkgroups`](\u002Fdocs\u002Fentities\u002Fworkgroups) |\n\nПолный список — [Поля сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Ffields). Пользовательские поля (`UF_*`) тоже принимаются.\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"name\": \"Иван\",\n    \"lastName\": \"Петров\",\n    \"email\": \"ivan.petrov@example.com\",\n    \"workPosition\": \"Менеджер\",\n    \"departmentId\": [1]\n  }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"name\": \"Иван\",\n    \"lastName\": \"Петров\",\n    \"email\": \"ivan.petrov@example.com\",\n    \"workPosition\": \"Менеджер\",\n    \"departmentId\": [1]\n  }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    name: 'Иван',\n    lastName: 'Петров',\n    email: 'ivan.petrov@example.com',\n    workPosition: 'Менеджер',\n    departmentId: [1],\n  }),\n})\n\nconst { success, data } = await res.json()\nconsole.log('User ID:', data.id)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    name: 'Иван',\n    lastName: 'Петров',\n    email: 'ivan.petrov@example.com',\n    workPosition: 'Менеджер',\n    departmentId: [1],\n  }),\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `success` | boolean | Всегда `true` при успехе |\n| `data.id` | number | ID созданного сотрудника |\n\nОтвет содержит полную запись со всеми полями сотрудника — формат тот же, что у [`GET \u002Fv1\u002Fusers\u002F:id`](\u002Fdocs\u002Fentities\u002Fusers\u002Fget).\n\nURL карточки сотрудника в Битрикс24 строится из `id`:\n\n```\nhttps:\u002F\u002F\u003Cportal>.bitrix24.ru\u002Fcompany\u002Fpersonal\u002Fuser\u002F\u003Cid>\u002F\n```\n\n`\u003Cportal>` — домен портала. Доступ ограничен правами сотрудника в Битрикс24.\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 1331,\n    \"xmlId\": \"74668002\",\n    \"active\": true,\n    \"name\": \"Иван\",\n    \"lastName\": \"Петров\",\n    \"email\": \"ivan.petrov@example.com\",\n    \"lastLogin\": null,\n    \"dateRegister\": \"2026-05-06T00:00:00.000Z\",\n    \"isOnline\": false,\n    \"timestampX\": {},\n    \"personalGender\": null,\n    \"personalBirthday\": null,\n    \"departmentId\": [1],\n    \"workPosition\": \"Менеджер\",\n    \"userType\": \"employee\"\n  }\n}\n```\n\n## Пример ответа при ошибке\n\n400 — email не передан или дублирует существующего сотрудника:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"BITRIX_ERROR\",\n    \"message\": \"wrong_email\",\n    \"hint\": \"Bitrix24 `user.add` returns `wrong_email` for several distinct cases, not only malformed email: (a) the email is already used by ANOTHER Bitrix24 user globally — check with GET \u002Fv1\u002Fusers?filter[EMAIL]=the-email first; (b) the email domain is not allowed by portal policy (some portals restrict external domains); (c) missing UF_DEPARTMENT for intranet users — it is required for intranet invites (try `UF_DEPARTMENT: [1]` for the root department); (d) for external users pass `EXTRANET: \\\"Y\\\"` + `SONET_GROUP_ID: [groupId]` instead of UF_DEPARTMENT. For a convenience wrapper, try POST \u002Fv1\u002Fusers\u002Finvite which sets sensible defaults. If the email is valid and unused, ask the portal admin to check user-invite settings.\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 400 | `BITRIX_ERROR` (`wrong_email`) | Email не передан, дублирует существующего сотрудника, не прошёл политику домена портала, либо для штатного сотрудника не указан `departmentId` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Известные особенности\n\n**Email должен быть глобально уникальным.** Битрикс24 проверяет уникальность среди всех сотрудников портала включая ранее деактивированных. Перед созданием — поиск через `GET \u002Fv1\u002Fusers?filter[EMAIL]=ivan.petrov@example.com`. Если запись найдена и деактивирована, верните её в строй через `PATCH \u002Fv1\u002Fusers\u002F:id { active: true }` — это сохранит историю действий и связи сотрудника, в отличие от создания дубля.\n\n**Неоднозначность ошибки `wrong_email`.** Битрикс24 возвращает `wrong_email` для нескольких разных ситуаций: email уже занят, домен запрещён политикой портала, у штатного сотрудника не указан `departmentId`, у внешнего — `SONET_GROUP_ID`. Сообщение не уточняет, какая именно. Чтобы разделить эти случаи на стороне Вайбкод, используйте [`POST \u002Fv1\u002Fusers\u002Finvite`](\u002Fdocs\u002Fentities\u002Fusers\u002Finvite) — обёртка возвращает явные коды (`EMAIL_REQUIRED`, `EMAIL_INVALID`, `SONET_GROUP_ID_REQUIRED`) до запроса в Битрикс24.\n\n## Смотрите также\n\n- [Пригласить сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Finvite) — обёртка с валидацией и значениями по умолчанию\n- [Поля сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Ffields) — полный список полей\n- [Список сотрудников](\u002Fdocs\u002Fentities\u002Fusers\u002Flist) — найти существующих\n- [Отделы](\u002Fdocs\u002Fentities\u002Fdepartments) — источник `departmentId`\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization)\n","\n## Пригласить сотрудника\n\n`POST \u002Fv1\u002Fusers\u002Finvite`\n\nСоздаёт нового сотрудника или приглашает внешнего пользователя на портал. Принимает поля в `camelCase` и `UPPER_SNAKE_CASE`, проставляет разумные значения по умолчанию и проверяет email до вызова Битрикс24 — возвращая понятные коды ошибок (`EMAIL_REQUIRED`, `EMAIL_INVALID`, `SONET_GROUP_ID_REQUIRED`) вместо общего `wrong_email`.\n\n## Поля запроса (body)\n\n| Параметр | Тип | Обяз. | Описание |\n|----------|-----|:-----:|---------|\n| `email` | string | да | Email — должен быть уникальным среди всех сотрудников портала. Базовая синтаксическая проверка происходит на стороне Вайбкод |\n| `name` | string | нет | Имя |\n| `lastName` | string | нет | Фамилия |\n| `secondName` | string | нет | Отчество |\n| `workPosition` | string | нет | Должность |\n| `workPhone` | string | нет | Рабочий телефон |\n| `workCompany` | string | нет | Название компании |\n| `personalPhone` | string | нет | Личный телефон |\n| `personalMobile` | string | нет | Мобильный телефон |\n| `personalBirthday` | string | нет | Дата рождения (ISO 8601) |\n| `personalGender` | string | нет | Пол: `M` — мужской, `F` — женский |\n| `personalCity` | string | нет | Город |\n| `departmentId` | number[] | нет | Массив ID отделов. По умолчанию `[1]` (корневой отдел) для штатных сотрудников. Список: `GET \u002Fv1\u002Fdepartments` |\n| `extranet` | string | нет | `\"Y\"` для приглашения внешнего пользователя. В этом случае `departmentId` игнорируется и обязателен `sonetGroupId` |\n| `sonetGroupId` | number[] | условно | Массив ID рабочих групп — обязателен при `extranet: \"Y\"`. Список: [`GET \u002Fv1\u002Fworkgroups`](\u002Fdocs\u002Fentities\u002Fworkgroups) |\n| `active` | boolean | нет | Признак активности (по умолчанию `true`) |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002Finvite\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"email\": \"ivan.petrov@example.com\",\n    \"name\": \"Иван\",\n    \"lastName\": \"Петров\",\n    \"workPosition\": \"Менеджер\"\n  }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002Finvite\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"email\": \"ivan.petrov@example.com\",\n    \"name\": \"Иван\",\n    \"lastName\": \"Петров\",\n    \"workPosition\": \"Менеджер\"\n  }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002Finvite', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    email: 'ivan.petrov@example.com',\n    name: 'Иван',\n    lastName: 'Петров',\n    workPosition: 'Менеджер',\n  }),\n})\n\nconst { success, data } = await res.json()\nconsole.log('Создан сотрудник ID:', data.id)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002Finvite', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    email: 'ivan.petrov@example.com',\n    name: 'Иван',\n    lastName: 'Петров',\n  }),\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `success` | boolean | Всегда `true` при успехе |\n| `data.id` | number | ID созданного сотрудника |\n| `data.user` | object | Полная запись только что созданного сотрудника — те же поля, что у [`GET \u002Fv1\u002Fusers\u002F:id`](\u002Fdocs\u002Fentities\u002Fusers\u002Fget) |\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 1331,\n    \"user\": {\n      \"id\": 1331,\n      \"xmlId\": \"74668002\",\n      \"active\": true,\n      \"name\": \"Иван\",\n      \"lastName\": \"Петров\",\n      \"email\": \"ivan.petrov@example.com\",\n      \"lastLogin\": null,\n      \"dateRegister\": \"2026-05-06T00:00:00.000Z\",\n      \"isOnline\": false,\n      \"timestampX\": {},\n      \"personalGender\": null,\n      \"departmentId\": [1],\n      \"workPosition\": \"Менеджер\",\n      \"userType\": \"employee\"\n    }\n  }\n}\n```\n\nHTTP-статус ответа — `201 Created`.\n\n## Пример ответа при ошибке\n\n400 — email не передан:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"EMAIL_REQUIRED\",\n    \"message\": \"EMAIL (or `email`) is required to invite a user.\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 400 | `EMAIL_REQUIRED` | В теле запроса нет `email` (или `EMAIL`) |\n| 400 | `EMAIL_INVALID` | Email не прошёл синтаксическую проверку Вайбкод |\n| 400 | `SONET_GROUP_ID_REQUIRED` | При `extranet: \"Y\"` не передан `sonetGroupId` |\n| 400 | `BITRIX_ERROR` (`wrong_email`) | Битрикс24 отклонил создание: email уже занят, домен запрещён политикой портала, или другая ошибка email |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Известные особенности\n\n**Зачем дефолт `departmentId: [1]`.** Без `UF_DEPARTMENT` Битрикс24 возвращает обобщённый `wrong_email` без указания причины — отсутствие отдела у штатного сотрудника одна из самых частых ловушек. Подстановка корневого отдела `[1]` устраняет её для типового случая «приглашаем сотрудника, конкретный отдел неизвестен». Если структура отделов важна — передавайте `departmentId` явно.\n\n**Уникальность email на портале.** Email проверяется среди всех сотрудников включая ранее деактивированных — при дубле Битрикс24 отдаст `BITRIX_ERROR: wrong_email`. Перед приглашением — поиск через `GET \u002Fv1\u002Fusers?filter[EMAIL]=ivan.petrov@example.com`. Если найден деактивированный, верните его в строй через [`PATCH \u002Fv1\u002Fusers\u002F:id { active: true }`](\u002Fdocs\u002Fentities\u002Fusers\u002Fupdate) — это сохранит историю и связи, в отличие от создания дубля.\n\n**Best-effort повторное чтение.** После успешного создания обёртка делает повторное чтение записи и кладёт её в `data.user`. Если вспомогательный вызов упал, `data.id` всё равно вернётся — сотрудник уже создан, повторное обращение [`GET \u002Fv1\u002Fusers\u002F:id`](\u002Fdocs\u002Fentities\u002Fusers\u002Fget) подгрузит запись.\n\n## Смотрите также\n\n- [Создать сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Fcreate) — низкоуровневая форма без значений по умолчанию\n- [Список сотрудников](\u002Fdocs\u002Fentities\u002Fusers\u002Flist) — поиск дубликата email перед приглашением\n- [Обновить сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Fupdate) — реактивация через `active: true`\n- [Отделы](\u002Fdocs\u002Fentities\u002Fdepartments) — источник `departmentId`\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization)\n","\n## Список сотрудников\n\n`GET \u002Fv1\u002Fusers`\n\nВозвращает список сотрудников портала с поддержкой фильтрации, сортировки и автопагинации. Метод не возвращает ботов, почтовых пользователей и пользователей Открытых линий.\n\n## Параметры\n\n| Параметр | Тип | По умолч. | Описание |\n|----------|-----|-----------|---------|\n| `limit` | number | `50` | Количество записей (до 5000). При `limit > 50` Вайбкод автоматически запрашивает несколько страниц у Битрикс24 |\n| `offset` | number | `0` | Пропустить N записей. При `offset > 0` рекомендуется `limit ≤ 500` |\n| `order` | object | — | Сортировка по любому полю записи. Пример: `?order[name]=asc` |\n| `filter` | object | — | Фильтрация по полям `GET \u002Fv1\u002Fusers\u002Ffields`.\u003Cbr>[Синтаксис фильтрации](\u002Fdocs\u002Ffiltering). Пример: `?filter[name]=Иван` |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers?limit=10&filter[active]=true\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers?limit=10&filter[active]=true\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\"\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers?limit=10&filter[active]=true', {\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n  },\n})\n\nconst { success, data, total } = await res.json()\nconsole.log(`Найдено ${total} сотрудников`)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers?limit=10&filter[active]=true', {\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n  },\n})\n\nconst { success, data, total } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `success` | boolean | Всегда `true` при успехе |\n| `data` | array | Массив сотрудников. Каждый элемент содержит все поля — см. [Поля сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Ffields) |\n| `total` | number | Общее количество записей под фильтр |\n| `page` | number | Текущая страница |\n| `limit` | number | Размер страницы |\n\nURL карточки любого сотрудника из массива `data` — его `id`:\n\n```\nhttps:\u002F\u002F\u003Cportal>.bitrix24.ru\u002Fcompany\u002Fpersonal\u002Fuser\u002F\u003Cid>\u002F\n```\n\n`\u003Cportal>` — домен портала. Доступ ограничен правами сотрудника в Битрикс24.\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 1,\n      \"xmlId\": \"28889266\",\n      \"active\": true,\n      \"name\": \"Мария\",\n      \"lastName\": null,\n      \"secondName\": \"Отчество\",\n      \"email\": \"maria@example.com\",\n      \"lastLogin\": \"2026-05-05T08:25:11.000Z\",\n      \"dateRegister\": \"2020-04-20T00:00:00.000Z\",\n      \"timeZone\": \"Europe\u002FKaliningrad\",\n      \"isOnline\": false,\n      \"timestampX\": {},\n      \"lastActivityDate\": {},\n      \"personalGender\": \"F\",\n      \"personalPhoto\": \"https:\u002F\u002Fcdn-ru.bitrix24.ru\u002F...\u002Fphoto.jpg\",\n      \"personalMobile\": \"+79991234567\",\n      \"workPosition\": null,\n      \"departmentId\": [1, 107, 47],\n      \"userType\": \"employee\"\n    },\n    {\n      \"id\": 29,\n      \"xmlId\": \"28936832\",\n      \"active\": true,\n      \"name\": \"Иван\",\n      \"lastName\": \"Петров\",\n      \"email\": \"ivan.petrov@example.com\",\n      \"departmentId\": [1],\n      \"userType\": \"employee\"\n    }\n  ],\n  \"total\": 30,\n  \"page\": 1,\n  \"limit\": 10\n}\n```\n\nПоказаны основные поля. Полный список — [Поля сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Ffields).\n\n## Пример ответа при ошибке\n\n403 — нет скоупа:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"SCOPE_DENIED\",\n    \"message\": \"This endpoint requires 'user' scope\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 400 | `INVALID_FILTER_FIELD` | Фильтр по несуществующему полю — список полей в `GET \u002Fv1\u002Fusers\u002Ffields` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Известные особенности\n\n**Семантика `filter[active]`.** `active: true` исключает деактивированных. `active: false` Битрикс24 не интерпретирует как «только деактивированные» — возвращаются все. Чтобы получить только деактивированных, просеивайте результат на стороне клиента по полю `active`.\n\n**Поля `WORK_*` и часть полей `PERSONAL_*` приходят в `UPPER_SNAKE_CASE`.** `WORK_COMPANY`, `WORK_DEPARTMENT`, `WORK_WWW`, `WORK_FAX`, `WORK_CITY`, `WORK_STATE`, `WORK_ZIP`, `WORK_COUNTRY` и аналогичные; `PERSONAL_STATE`, `PERSONAL_ZIP`, `PERSONAL_COUNTRY`, `PERSONAL_MAILBOX`, `PERSONAL_NOTES` — в оригинальных именах Битрикс24. UF-поля портала тоже сохраняют свои имена. Стандартные поля (`name`, `email`, `active`, `timeZone`, `userType`, `departmentId` и др.) — `camelCase`.\n\n**Поле `lastActivityDate` (объявлено `datetime`).** На практике приходит **пустым объектом `{}`**, либо ключ **отсутствует** вовсе — ISO-строка по этому полю в проверках не наблюдалась. `{}` — истинное значение в JS, поэтому `if (u.lastActivityDate)` ложно-срабатывает. То же у `timestampX` (всегда `{}`). Не парсьте как дату и не полагайтесь на truthy-проверку; сравнивайте тип (`typeof x === 'string'`). См. сводку по «пусто» в datetime-полях в [обзоре сущности](\u002Fdocs\u002Fentities\u002Fusers) (п. 7).\n\n## Смотрите также\n\n- [Получить сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Fget) — один по ID\n- [Поиск сотрудников](\u002Fdocs\u002Fentities\u002Fusers\u002Fsearch) — POST с фильтрами в теле\n- [Поля сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Ffields) — полный список полей\n- [Синтаксис фильтрации](\u002Fdocs\u002Ffiltering)\n- [Entity API](\u002Fdocs\u002Fentity-api) — order, пагинация\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization)\n","\n## Получить сотрудника\n\n`GET \u002Fv1\u002Fusers\u002F:id`\n\nВозвращает данные сотрудника по ID со всеми полями, включая пользовательские (`UF_*`).\n\n## Параметры\n\n| Параметр | Тип | Обяз. | Описание |\n|----------|-----|:-----:|---------|\n| `id` (path) | number | да | ID сотрудника |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002F29\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002F29\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\"\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002F29', {\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n  },\n})\n\nconst { success, data } = await res.json()\nconsole.log(`${data.name} ${data.lastName} — ${data.email}`)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002F29', {\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n  },\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\nОбъект сотрудника со всеми полями — см. [Поля сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Ffields).\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 29,\n    \"xmlId\": \"28936832\",\n    \"active\": true,\n    \"name\": \"Иван\",\n    \"lastName\": \"Петров\",\n    \"email\": \"ivan.petrov@example.com\",\n    \"lastLogin\": \"2026-03-30T14:39:25.000Z\",\n    \"dateRegister\": \"2020-04-23T00:00:00.000Z\",\n    \"timeZone\": \"Asia\u002FYekaterinburg\",\n    \"isOnline\": false,\n    \"timestampX\": {},\n    \"lastActivityDate\": {},\n    \"personalPhoto\": \"https:\u002F\u002Fcdn-ru.bitrix24.ru\u002F...\u002Fphoto.png\",\n    \"departmentId\": [1],\n    \"userType\": \"employee\"\n  }\n}\n```\n\n## Пример ответа при ошибке\n\n404 — сотрудник не найден:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"ENTITY_NOT_FOUND\",\n    \"message\": \"user 999999999 not found\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 400 | `INVALID_ID` | `:id` не является положительным целым числом |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` |\n| 404 | `ENTITY_NOT_FOUND` | Сотрудник с таким ID не найден или деактивирован и недоступен текущему ключу |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Известные особенности\n\n**Поля `WORK_*` и часть полей `PERSONAL_*` приходят в `UPPER_SNAKE_CASE`.** `WORK_COMPANY`, `WORK_DEPARTMENT`, `WORK_WWW`, `WORK_FAX`, `WORK_CITY`, `WORK_STATE`, `WORK_ZIP`, `WORK_COUNTRY` и аналогичные; `PERSONAL_STATE`, `PERSONAL_ZIP`, `PERSONAL_COUNTRY`, `PERSONAL_MAILBOX`, `PERSONAL_NOTES` — в оригинальных именах Битрикс24. UF-поля портала тоже сохраняют свои имена. Стандартные поля (`name`, `email`, `active`, `timeZone`, `userType`, `departmentId` и др.) — `camelCase`.\n\n## Смотрите также\n\n- [Поля сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Ffields) — все поля\n- [Список сотрудников](\u002Fdocs\u002Fentities\u002Fusers\u002Flist) — поиск с фильтрами\n- [Обновить сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Fupdate) — изменение полей\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization)\n","\n## Обновить сотрудника\n\n`PATCH \u002Fv1\u002Fusers\u002F:id`\n\nОбновляет поля существующего сотрудника. Передавайте только изменяемые поля. Требует прав администратора портала на стороне Битрикс24 — без них вызов отклоняется.\n\n## Поля запроса (body)\n\n| Параметр | Тип | Описание |\n|----------|-----|---------|\n| `workPosition` | string | Должность |\n| `departmentId` | number[] | Массив ID отделов. Список: `GET \u002Fv1\u002Fdepartments` |\n| `email` | string | Email — должен оставаться уникальным на портале |\n| `workPhone` \u002F `personalPhone` \u002F `personalMobile` | string | Телефоны |\n| `active` | boolean | Реактивировать (`true`) или деактивировать (`false`) — деактивация эквивалентна [`DELETE \u002Fv1\u002Fusers\u002F:id`](\u002Fdocs\u002Fentities\u002Fusers\u002Fdelete) |\n\nПолный список полей — [Поля сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Ffields). Пользовательские (`UF_*`) поля принимаются.\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X PATCH \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002F29\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"workPosition\": \"Старший менеджер\",\n    \"departmentId\": [1, 47]\n  }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X PATCH \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002F29\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"workPosition\": \"Старший менеджер\",\n    \"departmentId\": [1, 47]\n  }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002F29', {\n  method: 'PATCH',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    workPosition: 'Старший менеджер',\n    departmentId: [1, 47],\n  }),\n})\n\nconst { success, data } = await res.json()\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002F29', {\n  method: 'PATCH',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    workPosition: 'Старший менеджер',\n    departmentId: [1, 47],\n  }),\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `success` | boolean | Всегда `true` при успехе |\n| `data` | object | Обновлённый объект сотрудника со всеми полями — формат тот же, что у [`GET \u002Fv1\u002Fusers\u002F:id`](\u002Fdocs\u002Fentities\u002Fusers\u002Fget) |\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 29,\n    \"name\": \"Иван\",\n    \"lastName\": \"Петров\",\n    \"email\": \"ivan.petrov@example.com\",\n    \"active\": true,\n    \"workPosition\": \"Старший менеджер\",\n    \"departmentId\": [1, 47],\n    \"userType\": \"employee\"\n  }\n}\n```\n\n## Пример ответа при ошибке\n\n403 — обновление отклонено Битрикс24:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"UPDATE_FAILED\",\n    \"message\": \"Bitrix24 rejected user.update (result: false)\",\n    \"hint\": \"Bitrix24 returns false when the calling user lacks portal admin rights, when a read-only field was touched (isOnline, lastLogin, dateRegister, isAdmin), or when the target user ID does not exist. Verify the webhook\u002FOAuth identity is a portal admin.\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 400 | `INVALID_ID` | `:id` не является положительным целым числом |\n| 400 | `READONLY_FIELD` | В теле запроса передано readonly-поле (`id`, `isOnline`, `isAdmin`, `lastLogin`, `dateRegister`, `lastActivityDate`, `userType`, `timestampX`). Вайбкод отклоняет до вызова Битрикс24 |\n| 400 | `BITRIX_ERROR` | Битрикс24 отклонил поле — например, `wrong_email` при попытке поставить уже занятый email |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` |\n| 403 | `UPDATE_FAILED` | Битрикс24 вернул `result: false` для запроса на обновление. Чаще всего — у владельца ключа нет прав администратора портала |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Известные особенности\n\n**Изменение email.** Если новый email уже занят другим сотрудником портала, Битрикс24 вернёт `BITRIX_ERROR: wrong_email`. Перед PATCH — проверка через `GET \u002Fv1\u002Fusers?filter[EMAIL]=новый@example.com`.\n\n## Смотрите также\n\n- [Получить сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Fget) — текущие значения полей\n- [Поля сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Ffields) — какие поля можно изменить\n- [Деактивировать сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Fdelete) — обратимое деактивирование\n- [Batch](\u002Fdocs\u002Fbatch) — массовое обновление\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization)\n","\n## Деактивировать сотрудника\n\n`DELETE \u002Fv1\u002Fusers\u002F:id`\n\nДеактивирует сотрудника — снимает доступ к порталу, но сохраняет всю запись и её связи. Эндпоинт маппится на обновление поля активности (`active: false`); все данные и история действий остаются в Битрикс24. Восстановить доступ — `PATCH \u002Fv1\u002Fusers\u002F:id { active: true }`. Требует прав администратора портала.\n\n## Параметры\n\n| Параметр | Тип | Обяз. | Описание |\n|----------|-----|:-----:|---------|\n| `id` (path) | number | да | ID сотрудника |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X DELETE \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002F1331\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X DELETE \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002F1331\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\"\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002F1331', {\n  method: 'DELETE',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n  },\n})\n\nconst { success, data } = await res.json()\nif (success && data.deactivated) {\n  console.log(`Сотрудник ${data.id} деактивирован`)\n}\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002F1331', {\n  method: 'DELETE',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n  },\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `success` | boolean | Всегда `true` при успешной деактивации |\n| `data.id` | number | ID деактивированного сотрудника |\n| `data.active` | boolean | Всегда `false` после деактивации |\n| `data.deactivated` | boolean | Всегда `true` — явный маркер семантики операции |\n| `data.user` | object | Полная запись сотрудника после деактивации (best-effort: если повторное чтение записи не сработало, поле может отсутствовать — деактивация всё равно выполнена) |\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 1331,\n    \"active\": false,\n    \"deactivated\": true,\n    \"user\": {\n      \"id\": 1331,\n      \"name\": \"Иван\",\n      \"lastName\": \"Петров\",\n      \"email\": \"ivan.petrov@example.com\",\n      \"active\": false,\n      \"workPosition\": \"Менеджер\",\n      \"departmentId\": [1],\n      \"userType\": \"employee\"\n    }\n  }\n}\n```\n\n## Пример ответа при ошибке\n\n403 — у владельца ключа нет прав администратора портала:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"UPDATE_FAILED\",\n    \"message\": \"Bitrix24 rejected user.update for deactivation (result: false)\",\n    \"hint\": \"Bitrix24 returns false when the calling user lacks portal admin rights, or when the target user id does not exist. Verify the webhook\u002FOAuth identity is a portal admin.\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 400 | `INVALID_ID` | `:id` не является положительным целым числом |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` |\n| 403 | `UPDATE_FAILED` | Битрикс24 вернул `result: false`. Чаще всего — нет прав администратора портала; реже — сотрудника с таким ID не существует |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Известные особенности\n\n**Связи остаются.** После деактивации сотрудник продолжает значиться ответственным за сделки, автором комментариев, участником чатов. Email остаётся занятым — повторно использовать его при создании нового сотрудника не получится без предварительной реактивации существующего: [`PATCH \u002Fv1\u002Fusers\u002F:id { active: true }`](\u002Fdocs\u002Fentities\u002Fusers\u002Fupdate).\n\n**Best-effort повторное чтение записи.** Вайбкод пытается получить актуальную запись после успешной деактивации и кладёт её в `data.user`. Если вспомогательный вызов упал — поле отсутствует, но сама деактивация уже произведена и подтверждена. Повторный [`GET \u002Fv1\u002Fusers\u002F:id`](\u002Fdocs\u002Fentities\u002Fusers\u002Fget) подгрузит запись с `active: false`.\n\n## Смотрите также\n\n- [Обновить сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Fupdate) — реактивация через `active: true`\n- [Список сотрудников](\u002Fdocs\u002Fentities\u002Fusers\u002Flist) — поиск перед деактивацией\n- [Получить сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Fget) — проверить, что запись доступна\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization)\n","\n## Поиск сотрудников\n\n`POST \u002Fv1\u002Fusers\u002Fsearch`\n\nПоиск сотрудников с фильтрами в теле запроса и автопагинацией. Аналогичен [`GET \u002Fv1\u002Fusers`](\u002Fdocs\u002Fentities\u002Fusers\u002Flist), но через POST — удобнее для сложных запросов и больших массивов значений в фильтре.\n\n## Поля запроса (body)\n\n| Параметр | Тип | По умолч. | Описание |\n|----------|-----|-----------|---------|\n| `filter` | object | — | Фильтрация по полям `GET \u002Fv1\u002Fusers\u002Ffields`.\u003Cbr>[Синтаксис фильтрации](\u002Fdocs\u002Ffiltering). Пример: `{ \"filter\": { \"active\": true, \"lastName\": \"Иванов\" } }` |\n| `limit` | number | `50` | Количество записей (до 5000) |\n| `offset` | number | `0` | Пропустить N записей |\n| `order` | object | — | Сортировка: `{ \"NAME\": \"asc\" }` |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002Fsearch\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"filter\": { \"active\": true },\n    \"limit\": 10\n  }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002Fsearch\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"filter\": { \"active\": true },\n    \"limit\": 10\n  }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002Fsearch', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    filter: { active: true },\n    limit: 10,\n  }),\n})\n\nconst { success, data } = await res.json()\nconsole.log('Найдено:', data.length)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002Fsearch', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    filter: { active: true },\n    limit: 10,\n  }),\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `success` | boolean | Всегда `true` при успехе |\n| `data` | array | Массив сотрудников. Каждый элемент содержит все поля — см. [Поля сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Ffields) |\n\nURL карточки любого сотрудника из массива `data` — его `id`:\n\n```\nhttps:\u002F\u002F\u003Cportal>.bitrix24.ru\u002Fcompany\u002Fpersonal\u002Fuser\u002F\u003Cid>\u002F\n```\n\n`\u003Cportal>` — домен портала. Доступ ограничен правами сотрудника в Битрикс24.\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 1,\n      \"active\": true,\n      \"name\": \"Мария\",\n      \"lastName\": null,\n      \"email\": \"maria@example.com\",\n      \"departmentId\": [1, 107, 47]\n    },\n    {\n      \"id\": 29,\n      \"active\": true,\n      \"name\": \"Иван\",\n      \"lastName\": \"Петров\",\n      \"email\": \"ivan.petrov@example.com\",\n      \"departmentId\": [1]\n    }\n  ]\n}\n```\n\n## Пример ответа при ошибке\n\n403 — нет скоупа:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"SCOPE_DENIED\",\n    \"message\": \"This endpoint requires 'user' scope\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 400 | `INVALID_FILTER_FIELD` | Фильтр по несуществующему полю — список полей в `GET \u002Fv1\u002Fusers\u002Ffields` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Известные особенности\n\n**Семантика `filter[active]: false`.** Возвращает всех сотрудников, а не только деактивированных — Битрикс24 интерпретирует `ACTIVE = \"Y\"` как «исключить деактивированных», а другие значения как «без фильтра по статусу». Чтобы получить только деактивированных, делайте отдельную фильтрацию на стороне клиента по полю `active`.\n\n**Когда использовать search вместо list.** POST-search удобнее для длинных списков значений в фильтре (`{ \"id\": [1, 5, 12, 27, 99] }`) — query-строка GET-запроса имеет ограничения на длину, а body POST — нет. Для коротких фильтров обе формы эквивалентны.\n\n## Смотрите также\n\n- [Список сотрудников](\u002Fdocs\u002Fentities\u002Fusers\u002Flist) — GET-форма для простых фильтров\n- [Поля сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Ffields) — какие поля доступны\n- [Синтаксис фильтрации](\u002Fdocs\u002Ffiltering)\n- [Batch](\u002Fdocs\u002Fbatch) — несколько search в одном запросе\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization)\n","\n## Поля сотрудника\n\n`GET \u002Fv1\u002Fusers\u002Ffields`\n\nВозвращает полный список полей сущности «сотрудник», включая пользовательские (`UF_*`) поля портала.\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002Ffields\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\"\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002Ffields\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\"\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002Ffields', {\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n  },\n})\n\nconst { success, data } = await res.json()\nconsole.log('Полей:', Object.keys(data.fields).length)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002Ffields', {\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n  },\n})\n\nconst { success, data } = await res.json()\n```\n\n## Поля ответа\n\n| Поле | Битрикс24 | Тип | RO | Описание |\n|------|----------|-----|:--:|---------|\n| `id` | `ID` | number | да | Идентификатор сотрудника |\n| `name` | `NAME` | string | | Имя |\n| `lastName` | `LAST_NAME` | string | | Фамилия |\n| `secondName` | `SECOND_NAME` | string | | Отчество |\n| `email` | `EMAIL` | string | | Email — обязательное при создании, должно быть уникальным |\n| `active` | `ACTIVE` | boolean | | Признак активности (`true` — работает, `false` — деактивирован) |\n| `workPosition` | `WORK_POSITION` | string | | Должность |\n| `workPhone` | `WORK_PHONE` | string | | Рабочий телефон |\n| `personalPhone` | `PERSONAL_PHONE` | string | | Личный телефон |\n| `personalMobile` | `PERSONAL_MOBILE` | string | | Мобильный телефон |\n| `personalBirthday` | `PERSONAL_BIRTHDAY` | string | | Дата рождения (формат ISO 8601) |\n| `personalGender` | `PERSONAL_GENDER` | string | | Пол: `M` — мужской, `F` — женский |\n| `personalCity` | `PERSONAL_CITY` | string | | Город |\n| `personalPhoto` | `PERSONAL_PHOTO` | string | | URL фотографии |\n| `departmentId` | `UF_DEPARTMENT` | number[] | | Массив ID отделов. Список: `GET \u002Fv1\u002Fdepartments` |\n| `xmlId` | `XML_ID` | string | | Внешний идентификатор для интеграций |\n| `isAdmin` | `IS_ADMIN` | boolean | да | Признак администратора портала. Наполняется только в `GET \u002Fv1\u002Fusers\u002Fme` (`true`\u002F`false`\u002F`null`); в `GET \u002Fv1\u002Fusers\u002F:id` и списке недоступно |\n| `isOnline` | `IS_ONLINE` | boolean | да | Сотрудник сейчас в сети |\n| `dateRegister` | `DATE_REGISTER` | datetime | да | Дата регистрации в портале |\n| `lastLogin` | `LAST_LOGIN` | datetime | да | Дата последнего входа |\n| `lastActivityDate` | `LAST_ACTIVITY_DATE` | datetime | да | Дата последней активности |\n| `timeZone` | `TIME_ZONE` | string | | Часовой пояс сотрудника. Пример: `\"Europe\u002FMoscow\"` |\n| `title` | `TITLE` | string | | Обращение \u002F звание |\n| `personalWww` | `PERSONAL_WWW` | string | | Личный сайт |\n| `personalProfession` | `PERSONAL_PROFESSION` | string | | Профессия |\n| `personalIcq` | `PERSONAL_ICQ` | string | | ICQ (устаревшее поле Битрикс24) |\n| `personalFax` | `PERSONAL_FAX` | string | | Факс |\n| `personalPager` | `PERSONAL_PAGER` | string | | Пейджер |\n| `personalStreet` | `PERSONAL_STREET` | string | | Улица |\n| `userType` | `USER_TYPE` | string | да | Тип учётной записи: `\"employee\"` — штатный сотрудник, `\"extranet\"` — внешний пользователь |\n| `timestampX` | `TIMESTAMP_X` | datetime | да | Метка последнего изменения записи в Битрикс24. Для части пользователей возвращается пустым объектом `{}` |\n\n**Пользовательские поля** (`UF_*`) также возвращаются в ответах и принимаются при создании или обновлении. У пользовательского поля типа «список» (`enumeration`) в ответе есть массив `items` с возможными значениями (`ID`, `VALUE`, `DEF`, `XML_ID`) — при условии, что у ключа выдан скоуп `user.userfield`; без него поле возвращается с подписью, но без `items`.\n\n## Пример ответа\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"fields\": {\n      \"id\": { \"type\": \"number\", \"readonly\": true },\n      \"name\": { \"type\": \"string\", \"readonly\": false },\n      \"lastName\": { \"type\": \"string\", \"readonly\": false },\n      \"email\": { \"type\": \"string\", \"readonly\": false },\n      \"active\": { \"type\": \"boolean\", \"readonly\": false },\n      \"workPosition\": { \"type\": \"string\", \"readonly\": false },\n      \"departmentId\": { \"type\": \"array\", \"readonly\": false },\n      \"personalPhone\": { \"type\": \"string\", \"readonly\": false },\n      \"isAdmin\": { \"type\": \"boolean\", \"readonly\": true },\n      \"lastLogin\": { \"type\": \"datetime\", \"readonly\": true },\n      \"timeZone\": { \"type\": \"string\", \"readonly\": false },\n      \"userType\": { \"type\": \"string\", \"readonly\": true },\n      \"UF_DEPARTMENT\": { \"type\": \"string\", \"readonly\": false, \"label\": \"UF_DEPARTMENT\" },\n      \"UF_PHONE_INNER\": { \"type\": \"string\", \"readonly\": false, \"label\": \"UF_PHONE_INNER\" },\n      \"UF_USR_STATUS\": {\n        \"type\": \"enumeration\",\n        \"readonly\": false,\n        \"label\": \"Статус\",\n        \"items\": [\n          { \"ID\": \"1\", \"VALUE\": \"Новый\", \"DEF\": \"N\", \"XML_ID\": \"x1\" },\n          { \"ID\": \"2\", \"VALUE\": \"В работе\", \"DEF\": \"Y\", \"XML_ID\": \"x2\" }\n        ]\n      }\n    },\n    \"batch\": [\"create\", \"update\", \"delete\"]\n  }\n}\n```\n\nПоказаны несколько полей из общего списка. Реальный ответ содержит 30+ полей схемы в `camelCase`, не-mapped поля Битрикс24 в `UPPER_SNAKE_CASE` (`WORK_*`, часть `PERSONAL_*`) и UF-поля конкретного портала.\n\n## Пример ответа при ошибке\n\n403 — нет скоупа:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"SCOPE_DENIED\",\n    \"message\": \"This endpoint requires 'user' scope\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Смотрите также\n\n- [Создать сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Fcreate) — какие поля можно передать\n- [Обновить сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Fupdate) — какие поля можно изменить\n- [Список сотрудников](\u002Fdocs\u002Fentities\u002Fusers\u002Flist) — фильтрация и поиск\n- [Пользовательские поля](\u002Fdocs\u002Fuserfields) — управление UF-полями\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization)\n","\n## Агрегация сотрудников\n\n`POST \u002Fv1\u002Fusers\u002Faggregate`\n\nПодсчёт количества сотрудников с фильтрацией:\n\n- **`count`** — работает на любом запросе (с фильтром или без).\n- **`groupBy`** — по стандартным полям из списка агрегации (`active`, `isAdmin`, `isOnline`, `departmentId`, `workPosition`, `personalGender`, `personalCity`) и по пользовательским (UF) полям любого типа.\n- **`sum` \u002F `avg` \u002F `min` \u002F `max`** — только по UF-полям числовых типов: `integer`, `double`, `money`.\n\n## Поля запроса (body)\n\n| Параметр | Тип | Обяз. | Описание |\n|----------|-----|:-----:|---------|\n| `aggregate` | array | нет | Массив агрегаций. Каждый элемент: `{ \"field\": \"UF_*\", \"function\": \"sum\" }`. Для `count` поле — `\"*\"`. Без параметра — только `count` |\n| `filter` | object | нет | Фильтрация по полям `GET \u002Fv1\u002Fusers\u002Ffields`.\u003Cbr>[Синтаксис фильтрации](\u002Fdocs\u002Ffiltering). Принимает `camelCase` и `UPPER_SNAKE_CASE` |\n| `groupBy` | string \\| string[] | нет | Имя поля или массив (до 5). Поддерживаются: стандартные поля `active`, `isAdmin`, `isOnline`, `departmentId`, `workPosition`, `personalGender`, `personalCity`; а также любые UF-поля портала |\n\n## Примеры\n\n### curl — личный ключ\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002Faggregate\" \\\n  -H \"X-Api-Key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"filter\": { \"active\": true }\n  }'\n```\n\n### curl — OAuth-приложение\n\n```bash\ncurl -X POST \"https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002Faggregate\" \\\n  -H \"X-Api-Key: YOUR_APP_KEY\" \\\n  -H \"Authorization: Bearer USER_SESSION_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"filter\": { \"active\": true }\n  }'\n```\n\n### JavaScript — личный ключ\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002Faggregate', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_API_KEY',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    filter: { active: true },\n  }),\n})\n\nconst { success, data } = await res.json()\nconsole.log('Активных сотрудников:', data.count)\n```\n\n### JavaScript — OAuth-приложение\n\n```javascript\nconst res = await fetch('https:\u002F\u002Fvibecode.bitrix24.tech\u002Fv1\u002Fusers\u002Faggregate', {\n  method: 'POST',\n  headers: {\n    'X-Api-Key': 'YOUR_APP_KEY',\n    'Authorization': 'Bearer USER_SESSION_TOKEN',\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    filter: { active: true },\n  }),\n})\n\nconst { success, data } = await res.json()\n```\n\n> Для группировки по нескольким полям передайте массив: `\"groupBy\": [\"active\", \"workPosition\"]` (максимум 5).\n\n## Другие сценарии\n\nПодсчёт записей — `count` с полем `\"*\"`, самый быстрый запрос без выгрузки записей. Без массива `aggregate` результат тот же:\n\n```json\n{ \"aggregate\": [{ \"field\": \"*\", \"function\": \"count\" }] }\n```\n\nРаспределение по статусу активности — сколько сотрудников активно, сколько деактивировано:\n\n```json\n{ \"groupBy\": \"active\" }\n```\n\nГруппировка по UF-полю «Внутренний номер»:\n\n```json\n{ \"groupBy\": \"UF_PHONE_INNER\" }\n```\n\nСумма по числовому UF-полю с группировкой:\n\n```json\n{\n  \"aggregate\": [{ \"field\": \"UF_SALARY\", \"function\": \"sum\" }],\n  \"groupBy\": \"UF_DEPARTMENT\"\n}\n```\n\n## Поля ответа\n\n| Поле | Тип | Описание |\n|------|-----|---------|\n| `success` | boolean | Всегда `true` при успехе |\n| `data.count` | number | Количество записей под фильтр |\n| `data.aggregates` | object | Результаты агрегаций (пустой объект, если в запросе не было `aggregate`) |\n| `data.groups` | array | Группы (только при `groupBy`). Каждый элемент: значения полей группировки + `count` |\n| `data.meta.totalRecords` | number | Общее количество записей под фильтр |\n| `data.meta.recordsProcessed` | number | Количество обработанных записей |\n| `data.meta.truncated` | boolean | `true`, если попало больше 5000 записей и часть не вошла в выборку |\n\n## Пример ответа\n\nОтвет на запрос `count` без `groupBy`:\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"count\": 57,\n    \"aggregates\": {},\n    \"meta\": {\n      \"totalRecords\": 57,\n      \"recordsProcessed\": 0,\n      \"truncated\": false\n    }\n  }\n}\n```\n\nБез `groupBy` поле `data.groups` в ответе отсутствует.\n\n## Пример ответа при ошибке\n\n400 — `groupBy` по несуществующему полю (сообщение содержит список доступных стандартных и UF-полей):\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"INVALID_PARAMS\",\n    \"message\": \"groupBy field 'nonexistent' is not aggregatable on this entity. Available: active, isAdmin, isOnline, departmentId, workPosition, personalGender, personalCity. User-defined: UF_DEPARTMENT (string), UF_PHONE_INNER (string), UF_EMPLOYMENT_DATE (string), UF_SKILLS (string), UF_INTERESTS (string), UF_LINKEDIN (string), UF_FACEBOOK (string).\"\n  }\n}\n```\n\n## Ошибки\n\n| HTTP | Код | Описание |\n|------|-----|---------|\n| 400 | `INVALID_PARAMS` | Несуществующее или недопустимое поле в `groupBy` или `aggregate.field` — сообщение содержит список доступных полей |\n| 400 | `INVALID_PARAMS` | UF-поле нечислового типа (`string`, `enumeration`, `date`) в `sum`\u002F`avg`\u002F`min`\u002F`max` — сообщение называет тип |\n| 400 | `INVALID_PARAMS` | Больше 5 полей в `groupBy` |\n| 401 | `TOKEN_MISSING` | API-ключ не имеет настроенных токенов |\n| 403 | `SCOPE_DENIED` | API-ключ не имеет скоупа `user` |\n\nПолный список общих ошибок API — [Ошибки](\u002Fdocs\u002Ferrors).\n\n## Известные особенности\n\n**`count` vs числовые функции.** `count` считается одним вызовом Битрикс24 на любом объёме. `sum`\u002F`avg`\u002F`min`\u002F`max` подгружают записи постранично (максимум 5000), считают на стороне Вайбкод. При более 5000 записей под фильтр — `meta.truncated: true`, агрегация по первым 5000. Для точного подсчёта на больших выборках — `count` или сужение фильтра.\n\n**Money-поля.** UF-поля типа `money` хранятся в формате `\"сумма|валюта\"` (`\"50000|RUB\"`) — агрегат извлекает числовую часть автоматически, складывать можно без парсинга.\n\n## Смотрите также\n\n- [Список сотрудников](\u002Fdocs\u002Fentities\u002Fusers\u002Flist) — выгрузка записей с пагинацией\n- [Поля сотрудника](\u002Fdocs\u002Fentities\u002Fusers\u002Ffields) — UF-поля приходят в общем списке\n- [Синтаксис фильтрации](\u002Fdocs\u002Ffiltering)\n- [Лимиты и оптимизация](\u002Fdocs\u002Foptimization)\n"]