
# Employees

Manage Bitrix24 account employees: list, get by ID, invite a new one, update, deactivate. The entity stores an employee's contact data, position, department, and user fields (UF).

Bitrix24 API: `user.*`
Scope: `user`

## Operations

- [Create employee](./users/create.md) — `POST /v1/users`
- [Invite employee](./users/invite.md) — `POST /v1/users/invite`
- [List employees](./users/list.md) — `GET /v1/users`
- [Get employee](./users/get.md) — `GET /v1/users/:id`
- [Update employee](./users/update.md) — `PATCH /v1/users/:id`
- [Deactivate employee](./users/delete.md) — `DELETE /v1/users/:id`
- [Search employees](./users/search.md) — `POST /v1/users/search`
- [Employee fields](./users/fields.md) — `GET /v1/users/fields`
- [Aggregate employees](./users/aggregate.md) — `POST /v1/users/aggregate`

## Key fields

| Field | Description |
|------|---------|
| `id` | Employee identifier |
| `name` / `lastName` / `secondName` | First name, last name, middle name |
| `email` | Email — required on creation, must be unique across all employees in the Bitrix24 account |
| `active` | Activity flag: `true` — active, `false` — deactivated |
| `workPosition` | Position |
| `departmentId` | Array of the employee's department IDs. List: `GET /v1/departments` |
| `personalPhone` / `personalMobile` / `workPhone` | Phones |
| `isAdmin` | Bitrix24 account administrator flag (read-only). Populated **only on `GET /v1/users/me`**, tri-state: `true` — admin, `false` — not admin, `null` — could not be determined (a transient failure; the profile is still returned, this is not an error) — usable for server-side permission checks. **On `GET /v1/users/:id` and the `GET /v1/users` list it is unavailable**: `user.get` does not return it (`data.isAdmin` = `undefined`); the verdict is available only for the current session user. |

Full field list — [`GET /v1/users/fields`](/docs/entities/users/fields).

## What to know before you start

1. **Creation requires email.** The `email` field is required and must be unique across the whole Bitrix24 account. A duplicate returns `BITRIX_ERROR: wrong_email` without an explicit reason — Bitrix24 uses this code for several different cases (see below).
2. **Two endpoints for creation.** [`POST /v1/users`](/docs/entities/users/create) — the plain entity form, proxies Bitrix24 errors as-is. [`POST /v1/users/invite`](/docs/entities/users/invite) — a wrapper that prefills `departmentId: [1]` for in-house employees and validates email explicitly on the Vibecode side (`EMAIL_REQUIRED`, `EMAIL_INVALID`). For integrations, `/invite` is preferable — it has clear error codes.
3. **PATCH and DELETE require Bitrix24 account administrator rights.** Bitrix24 applies an employee update only if the key owner has admin rights on the Bitrix24 account. Without them Bitrix24 returns `result: false`, and Vibecode wraps this into `403 UPDATE_FAILED` with details in the `hint` field.
4. **`DELETE /v1/users/:id` is a deactivation.** The endpoint revokes the employee's access to the Bitrix24 account but keeps the entire record and its relations (deal owner, comment author, chat participant). Under the hood it maps to updating the activity field (`active: false`); the response carries an explicit `deactivated: true` marker. To restore access — `PATCH /v1/users/:id { active: true }`. Data is not lost.
5. **Read-only fields.** `id`, `isOnline`, `isAdmin`, `lastLogin`, `dateRegister`, `lastActivityDate`, `userType`, `timestampX` are populated by the system. An attempt to pass them to `PATCH /v1/users/:id` is rejected upfront with `400 READONLY_FIELD` — the Bitrix24 call does not happen.
6. **`WORK_*` / `PERSONAL_*` usually do not arrive, and Bitrix24 omits empty fields.** Standard filled fields (`name`, `email`, `active`, `departmentId`, `timeZone`, `userType`, etc.) — `camelCase`. Fields `WORK_COMPANY`, `WORK_DEPARTMENT`, `PERSONAL_STATE`, `PERSONAL_ZIP` and the like are in practice **absent** from the response (Bitrix24 does not return unfilled fields); if such a field does arrive, it keeps its original `UPPER_SNAKE_CASE` name (not camelCased). So the key may **not exist at all** — do not rely on its presence.
7. **"Empty" in datetime fields is encoded three ways.** `timestampX` and `lastActivityDate` (declared `datetime`) arrive as an **empty object `{}`**, not a string/`null` (`new Date(u.timestampX)` → `Invalid Date`; `if (u.lastActivityDate)` is **truthy** even without activity). `lastActivityDate` may additionally be **absent** as a key. `lastLogin` returns `null` when there was no login. `dateRegister` is always an ISO string (UTC midnight). Check "there was activity" with a type comparison (`typeof x === 'string'`), not a truthy check.
8. **External employees (extranet).** When creating an extranet user `EXTRANET: "Y"`, the required field is `SONET_GROUP_ID` (array of workgroup IDs) instead of `departmentId`. `/invite` explicitly returns `400 SONET_GROUP_ID_REQUIRED` if neither is passed.

## Typical scenario

1. Find an employee by part of the name or email: [`GET /v1/users?filter[NAME]=John`](/docs/entities/users/list).
2. Get the full data of a single employee: [`GET /v1/users/:id`](/docs/entities/users/get).
3. Invite a new one via the Vibecode wrapper: [`POST /v1/users/invite`](/docs/entities/users/invite).
4. Update position or department: [`PATCH /v1/users/:id`](/docs/entities/users/update).
5. If the employee has left — deactivate: [`DELETE /v1/users/:id`](/docs/entities/users/delete). Restore — `PATCH /v1/users/:id { active: true }`.

## Limits

| Limit | Value |
|-------|----------|
| Maximum records per request | 5000 (`limit ≤ 5000`) |
| Auto-pagination | enabled when `limit > 50` |
| `offset` on large result sets | `limit ≤ 500` recommended when `offset ≥ 2500` |
| Batch requests | up to 50 operations in [`POST /v1/batch`](/docs/batch) |
| Rate limit | shared across the Vibe API — see [Limits and optimization](/docs/optimization) |

## See also

- [Departments](/docs/entities/departments) — `departmentId` comes from `GET /v1/departments`
- [Entity API](/docs/entity-api) — general principles of working with entities
- [Filtering syntax](/docs/filtering)
- [Batch](/docs/batch) — bulk operations
- [Entities reference](/docs/entities-index)
