API

Serhii
От Serhii
7 статьи

Как получить access token

Access token необходим для авторизации последующих API-запросов в LMS Smart Way. После получения токена вы передаёте его в заголовке Authorization с типом Bearer и используете для обращения к доступным endpoint’ам в соответствии со scope, которые вложены в токен. Эта статья показывает, как получить токен, что именно возвращает API в ответе и на что обратить внимание перед интеграцией. Если вы только начинаете настройку интеграции, сначала убедитесь, что у вас есть действительный company_api_key. Предпосылки - У вас должен быть действительный company_api_key вашей компании. - Запрос на получение токена необходимо выполнять на endpoint /api/v1/auth/token. - API key передаётся в заголовке X-API-Key. - Полученный access token используется только для последующих вызовов API и не заменяет собой API key. Запрос curl -X POST 'https://smartway.pro/api/v1/auth/token' \ -H 'X-API-Key: <company_api_key>' Успешный ответ { "access_token": "<short_lived_jwt>", "token_type": "Bearer", "expires_in": 900, "scope": "academy.read academy.write employees.read employees.write tests.read tests.write files.read" } Зафиксированные правила ответа - access_token — короткоживущий JWT для последующих вызовов public API - token_type — всегда Bearer - expires_in — TTL в секундах - scope — список scope-ов, разделённых пробелами, вложенных в токен Что внутри access token - JWT содержит claim companyId для tenant isolation. - JWT также содержит claim hrEmail — email HRADMIN, который создал или ротировал текущий активный API key компании. - Если API key сгенерирует или ротирует другой HRADMIN, то новые токены уже будут содержать другой hrEmail, и именно он будет использоваться для последующих employee write-операций. Как использовать access token в последующих запросах После успешного получения токена передавайте его в заголовке Authorization в формате Bearer <access_token>. Именно этот токен используется для авторизации последующих запросов к public API. Перед выполнением запроса проверяйте, что токен ещё не истёк. Если срок действия завершился, получите новый access token повторным вызовом endpoint’а авторизации.

Обновлено Mar 28, 2026

Правила текущей реализации API LMS

Public API использует схему: company API key -> short-lived Bearer token Правила текущей реализации: - API key принадлежит компании, а не отдельному пользователю. - Для v1 разрешен один активный API key на компанию. - Управляет ключом только пользователь с ролью HRADMIN в cab > Settings > Company. - Полный секрет показывается только один раз — сразу после генерации или ротации. - После ротации предыдущий ключ становится невалидным сразу. - Интегратор получает access token через POST /v1/auth/token и далее использует Authorization: Bearer <token>. - Refresh token для интегратора в v1 не используется: после завершения TTL access token интегратор повторно вызывает POST /v1/auth/token. Base URL и общие правила вызова 1. Base URL Текущий base URL: - https://smartway.pro/api 2. Общие правила - Формат бизнес-ответов: application/json - Формат ошибок: application/problem+json - Версионирование: major-версия в URI (/v1/...) - Для корреляции запросов рекомендуется передавать traceparent

Обновлено Mar 28, 2026

Как получить список сотрудников через API?

GET /v1/employees возвращает страницу сотрудников. Если query-параметры не переданы, API применяет значения по умолчанию: page = 0 и size = 50. Endpoint | Параметр | Значение | | -------------- | ---------------------------------------------------- | | Method | GET | | Path | /v1/employees | | Base URL | https://smartway.pro/api | | Auth | Bearer token | | Required scope | employees.read | Назначение Endpoint используется для получения постраничного списка сотрудников в рамках компании из Bearer token. Endpoint поддерживает пагинацию, поиск по ФИО и фильтры по департаменту и должности. Предусловия - Клиент должен передать валидный Bearer token. - Token должен содержать company context. - Token должен содержать scope employees.read. - idCompany не передаётся внешним клиентом. BFF берёт companyId только из Bearer token. - Текстовые query-параметры поддерживают UTF-8 и должны передаваться как стандартный URL-encoded query string. Запрос Query parameters | Параметр | Тип | Обязательный | Описание | | ------------ | ------- | ---------------- | ----------------------------------------------------------------------- | | page | int32 | нет | Номер страницы. Значение по умолчанию: 0. | | size | int32 | нет | Размер страницы. Значение по умолчанию: 50. | | q | string | нет | Поиск по ФИО с частичным совпадением. Поиск по email не поддерживается. | | department | string | нет | Фильтр по департаменту. | | jobTitle | string | нет | Фильтр по должности. | curl пример Вызов без параметров curl -X GET 'https://smartway.pro/api/v1/employees' \ -H 'Authorization: Bearer <access_token>' \ -H 'Accept: application/json' Вызов с параметрами curl -X GET 'https://smartway.pro/api/v1/employees?page=0&size=20&q=Иван' \ -H 'Authorization: Bearer <access_token>' \ -H 'Accept: application/json' Вызов с несколькими UTF-8 параметрами curl -G 'https://smartway.pro/api/v1/employees' \ --data-urlencode 'page=0' \ --data-urlencode 'size=20' \ --data-urlencode 'q=Иван' \ --data-urlencode 'department=Управление' \ --data-urlencode 'jobTitle=Менеджер' \ -H 'Authorization: Bearer <access_token>' \ -H 'Accept: application/json' Ответ Успешный ответ: 200 OK. Возвращает EmployeeListResponse. { "data": [ { "employeeId": 4329, "candidateId": 10602, "email": "employee@example.com", "fullName": "Имя Фамилия", "name": "Имя", "surname": "Фамилия", "gender": "Female", "department": "КЛ", "departments": [ "КЛ" ], "jobTitle": "Менеджер", "jobTitles": [ "Менеджер" ], "phone": "+380000000000", "active": true } ], "meta": { "page": 0, "size": 50, "totalElements": 385, "totalPages": 8, "hasNext": true } } Поля ответа EmployeeListResponse | Поле | Тип | Описание | | -------- | ---------- | --------------------------------------- | | data | Employee[] | Список сотрудников на текущей странице. | | meta | object | Метаданные пагинации. | Employee | Поле | Тип | Описание | | ----------- | -------- | ------------------------------------------------------- | | employeeId | int64 | ID сотрудника. | | candidateId | int64 | ID связанного кандидата. | | email | string | Email сотрудника. | | fullName | string | Полное имя, которое сервер формирует из name + surname. | | name | string | Имя. | | surname | string | Фамилия. | | gender | string | Пол. | | department | string | Основной департамент. | | departments | string[] | Набор департаментов. | | jobTitle | string | Основная должность. | | jobTitles | string[] | Набор должностей. | | phone | string | Телефон. | | active | boolean | Признак активности. | Pagination meta | Поле | Тип | Описание | | ------------- | ------- | ------------------------------------------ | | page | int32 | Номер текущей страницы. Нумерация 0-based. | | size | int32 | Размер страницы. | | totalElements | int64 | Общее количество найденных элементов. | | totalPages | int32 | Общее количество страниц. | | hasNext | boolean | Признак наличия следующей страницы. | Бизнес-логика - Все query-параметры необязательные. - Если endpoint вызвать без параметров, API возвращает первую страницу сотрудников: page = 0, size = 50. - Параметр page является 0-based: page = 0 — первая страница, page = 1 — вторая страница. - BFF берёт companyId только из Bearer token. - idCompany не передаётся внешним клиентом. - Поиск q работает по ФИО с частичным совпадением. - Поиск по email не поддерживается. - Параметры q, department и jobTitle поддерживают UTF-8. - Параметры можно комбинировать. Совокупность параметров применяется через логику AND. - Для доступа нужен scope employees.read. Edge cases Edge cases | Сценарий | Поведение API | | ------------------------------------------------------- | ------------------------------------------------------------- | | Query-параметры не переданы | API применяет page = 0 и size = 50. | | page = 0 | Возвращается первая страница. | | page = 1 | Возвращается вторая страница. | | Передан q | API ищет по ФИО с частичным совпадением. | | Передан email в q | Поиск по email не поддерживается. | | Переданы department и jobTitle | Фильтры комбинируются через AND. | | Передано UTF-8 значение, например department=Управление | Значение валидно, если передано как URL-encoded query string. | | Token без company context | API возвращает 403 Forbidden. | Ошибки Error responses | HTTP status | Когда возникает | | ------------------------- | ------------------------------------------------ | | 400 Bad Request | Некорректные query-параметры. | | 401 Unauthorized | Bearer token отсутствует или невалиден. | | 403 Forbidden | Недостаточно прав или token без company context. | | 500 Internal Server Error | Неожиданная ошибка BFF. | | 503 Service Unavailable | Сбой внутренней интеграции BFF -> back2. | Использование - Первый тест интеграции без query-параметров. - Получение следующей страницы через page. - Изменение размера страницы через size. - Поиск сотрудника по ФИО через q. - Фильтрация сотрудников по department или jobTitle. - Комбинирование поиска и фильтров для узкой выборки. Типичные ошибки Typical integration mistakes | Типичная ошибка | Как правильно | | --------------------------------------- | ------------------------------------------------------------- | | Считать, что page = 1 — первая страница | Используйте page = 0 для первой страницы. | | Искать сотрудника по email через q | q поддерживает поиск по ФИО, а не по email. | | Передавать idCompany в query string | Не передавайте idCompany; companyId берётся из Bearer token. | | Не кодировать UTF-8 значения в URL | Передавайте текстовые параметры как URL-encoded query string. | | Использовать token без employees.read | Для endpoint-а нужен scope employees.read. | FAQ Можно ли вызвать endpoint без query-параметров? Да. API применит page = 0 и size = 50. С какой страницы начинается пагинация? С page = 0. Поддерживается ли поиск по email? Нет. Параметр q ищет по ФИО с частичным совпадением. Можно ли комбинировать фильтры? Да. Параметры комбинируются через логику AND. Нужно ли передавать idCompany? Нет. BFF берёт companyId из Bearer token.

Обновлено Apr 25, 2026

Как получить сотрудника по ID через API?

GET /v1/employees/{employeeId} возвращает одного сотрудника по ID в рамках tenant-контекста из Bearer token. Endpoint | Параметр | Значение | | -------------- | ---------------------------------------------------- | | Method | GET | | Path | /v1/employees/{employeeId} | | Base URL | https://smartway.pro/api | | Auth | Bearer token | | Required scope | employees.read | Назначение Endpoint используется для получения детальной информации об одном сотруднике. Поиск выполняется только в рамках tenant-контекста, определённого Bearer token. Предусловия - Клиент должен передать валидный Bearer token. - Token должен содержать company context. - Token должен содержать scope employees.read. - idCompany не передаётся отдельно. - employeeId должен принадлежать сотруднику в рамках текущего tenant-а. Запрос Path parameters | Параметр | Тип | Обязательный | Описание | | ------------ | ------- | ---------------- | -------------- | | employeeId | int64 | да | ID сотрудника. | curl пример Получить сотрудника по ID curl -X GET 'https://smartway.pro/api/v1/employees/3114' \ -H 'Authorization: Bearer <access_token>' \ -H 'Accept: application/json' Ответ Успешный ответ: 200 OK. Возвращает Employee. { "employeeId": 4329, "candidateId": 10602, "email": "employee@example.com", "fullName": "Имя Фамилия", "name": "Имя", "surname": "Фамилия", "gender": "Female", "department": "КЛ", "departments": [ "КЛ" ], "jobTitle": "Менеджер", "jobTitles": [ "Менеджер" ], "phone": "+380000000000", "active": true } Поля ответа Employee | Поле | Тип | Описание | | ----------- | -------- | ------------------------------------------------------- | | employeeId | int64 | ID сотрудника. | | candidateId | int64 | ID связанного кандидата. | | email | string | Email сотрудника. | | fullName | string | Полное имя, которое сервер формирует из name + surname. | | name | string | Имя. | | surname | string | Фамилия. | | gender | string | Пол. | | department | string | Основной департамент. | | departments | string[] | Набор департаментов. | | jobTitle | string | Основная должность. | | jobTitles | string[] | Набор должностей. | | phone | string | Телефон. | | active | boolean | Признак активности. | Бизнес-логика - BFF берёт companyId из Bearer token. - idCompany не передаётся отдельным параметром. - Поиск сотрудника выполняется в рамках tenant-контекста из Bearer token. - Если employeeId не найден в текущем tenant-е, API возвращает 404 Not Found. - Для доступа нужен scope employees.read. - fullName является производным полем и формируется сервером из name + surname. Edge cases Edge cases | Сценарий | Поведение API | | ---------------------------------------- | ----------------------------------------------------------- | | employeeId существует в текущем tenant-е | API возвращает 200 OK и Employee. | | employeeId не найден в текущем tenant-е | API возвращает 404 Not Found. | | employeeId существует в другой компании | API не возвращает сотрудника вне текущего tenant-контекста. | | Bearer token без company context | API возвращает 403 Forbidden. | | Клиент передаёт idCompany | Endpoint не использует idCompany из клиентского запроса. | Ошибки Error responses | HTTP status | Когда возникает | | ------------------------- | ------------------------------------------------ | | 400 Bad Request | Некорректный запрос. | | 401 Unauthorized | Bearer token отсутствует или невалиден. | | 403 Forbidden | Недостаточно прав или token без company context. | | 404 Not Found | Сотрудник не найден в рамках текущего tenant-а. | | 500 Internal Server Error | Неожиданная ошибка BFF. | | 503 Service Unavailable | Сбой внутренней интеграции BFF -> back2. | Использование - Получить карточку сотрудника по employeeId. - Проверить результат создания или обновления сотрудника. - Синхронизировать данные одного сотрудника во внешней системе. - Проверить, доступен ли employeeId в рамках текущего tenant-а. Типичные ошибки Typical integration mistakes | Типичная ошибка | Как правильно | | ------------------------------------------- | ----------------------------------------------------------- | | Передавать idCompany вместе с employeeId | Не передавайте idCompany; tenant определяется Bearer token. | | Использовать token без employees.read | Для чтения сотрудника нужен scope employees.read. | | Ожидать доступ к сотруднику другой компании | API ищет только в текущем tenant-контексте. | | Считать 404 технической ошибкой | 404 означает, что сотрудник не найден в текущем tenant-е. | FAQ Нужно ли передавать idCompany? Нет. companyId берётся из Bearer token. Какой scope нужен? employees.read. Что будет, если employeeId не найден? API вернёт 404 Not Found. Возвращается ли fullName? Да. fullName возвращается как поле Employee и формируется сервером из name + surname.

Обновлено Apr 25, 2026

Как добавить сотрудника через API?

POST /v1/employees создаёт сотрудника. Обязательные поля body: email, name, surname, gender и active. Для доступа нужен scope employees.write. Endpoint | Параметр | Значение | | -------------- | ---------------------------------------------------- | | Method | POST | | Path | /v1/employees | | Base URL | https://smartway.pro/api | | Auth | Bearer token | | Required scope | employees.write | Назначение Endpoint используется для создания нового сотрудника в рамках компании из Bearer token. Значение active управляет не только бизнес-флагом, но и созданием или отсутствием связанного пользователя в Keycloak. Предусловия - Клиент должен передать валидный Bearer token. - Token должен содержать company context. - Token должен содержать scope employees.write. - idCompany не передаётся в body или query string. - hrEmail не передаётся внешним клиентом; BFF берёт его из Bearer token. - В текущей реализации Idempotency-Key не используется. Запрос Body parameters | Поле | Тип | Обязательное | Описание | | ----------- | -------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | email | string | да | Email сотрудника. | | name | string | да | Имя сотрудника. Это source of truth для формирования fullName при создании. | | surname | string | да | Фамилия сотрудника. Это source of truth для формирования fullName при создании. | | gender | string | да | Допустимы только значения Male или Female. | | active | boolean | да | Допустимы только JSON-boolean значения true или false. true создаёт или синхронизирует доступ к личному кабинету через Keycloak; false создаёт сотрудника без такого доступа. | | department | string | нет | Основной департамент. Если не передать, сохраняется null. | | departments | string[] | нет | Набор департаментов. Если не передать, коллекция остаётся пустой. | | jobTitle | string | нет | Основная должность. Если не передать, сохраняется null. | | jobTitles | string[] | нет | Набор должностей. Если не передать, коллекция остаётся пустой. | | phone | string | нет | Телефон. Если не передать, сохраняется null. | | notes | string | нет | Примечания. Если не передать, сохраняется null. | curl пример Создать сотрудника с primary-полями и массивами curl -X POST 'https://smartway.pro/api/v1/employees' \ -H 'Authorization: Bearer <access_token>' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ --data-binary @- <<'JSON' { "email": "employee@example.com", "name": "Иван", "surname": "Петренко", "gender": "Female", "active": false, "department": "Управление", "departments": ["КЛ"], "jobTitle": "Менеджер", "jobTitles": ["Координатор"], "phone": "+380000000000", "notes": "Новый сотрудник public API" } JSON Создать сотрудника только с массивами departments/jobTitles curl -X POST 'https://smartway.pro/api/v1/employees' \ -H 'Authorization: Bearer <access_token>' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ --data-binary @- <<'JSON' { "email": "employee@example.com", "name": "Иван", "surname": "Петренко", "gender": "Male", "active": true, "departments": ["Управление", "КЛ"], "jobTitles": ["Менеджер", "Координатор"], "phone": "+380000000000", "notes": "Новый сотрудник public API" } JSON Ответ Успешный ответ: 201 Created. Возвращает созданный Employee. { "employeeId": 4432, "candidateId": 10748, "email": "employee@example.com", "fullName": "Иван Петренко", "name": "Иван", "surname": "Петренко", "gender": "Female", "department": "Управление", "departments": [ "КЛ", "Управление" ], "jobTitle": "Менеджер", "jobTitles": [ "Координатор", "Менеджер" ], "phone": "+380000000000", "active": false } Поля ответа Employee | Поле | Тип | Описание | | ----------- | -------- | ------------------------------------------------------- | | employeeId | int64 | ID сотрудника. | | candidateId | int64 | ID связанного кандидата. | | email | string | Email сотрудника. | | fullName | string | Полное имя, которое сервер формирует из name + surname. | | name | string | Имя. | | surname | string | Фамилия. | | gender | string | Пол. | | department | string | Основной департамент. | | departments | string[] | Набор департаментов. | | jobTitle | string | Основная должность. | | jobTitles | string[] | Набор должностей. | | phone | string | Телефон. | | active | boolean | Признак активности. | Бизнес-логика - BFF определяет companyId только из Bearer token. - BFF берёт hrEmail из Bearer token. hrEmail равен email пользователя с ролью HRADMIN, который создал или ротировал активный API key компании. - Если активный API key будет ротирован другим HRADMIN, следующие create-операции автоматически начнут использовать его hrEmail. - Повторный одинаковый POST не создаёт дубль, если уже существует employee с таким же email; API возвращает 409 Conflict. - gender принимает только Male или Female. - active принимает только JSON-boolean true или false. - active = true создаёт или синхронизирует связанный пользовательский аккаунт в Keycloak и открывает доступ к личному кабинету. - active = false создаёт сотрудника без доступа к личному кабинету, то есть без пользователя в Keycloak. - fullName в ответе формируется сервером из name + surname. - Если передан только departments или jobTitles, первый элемент массива становится primary-значением в department или jobTitle. - Если передано и одиночное поле, и массив, одиночное поле имеет приоритет как primary, а массив дополняется уникальными значениями. - Если department, jobTitle, phone или notes не переданы, в соответствующих одиночных полях сохраняется null. - Если departments или jobTitles не переданы, соответствующие коллекции остаются пустыми. - В ответе departments и jobTitles возвращаются в стабильно отсортированном виде. Edge cases Edge cases | Сценарий | Поведение API | | ----------------------------------------- | --------------------------------------------------------------------------------------- | | Отсутствует required-поле | API возвращает 400 Bad Request. | | gender имеет значение не Male и не Female | API возвращает 400 Bad Request с пояснением. | | active передан строкой или числом | API возвращает 400 Bad Request, потому что active должен быть JSON-boolean. | | email уже существует | API возвращает 409 Conflict. | | Передан только departments | Первый элемент массива становится department. | | Переданы department и departments | department остаётся primary, а departments дополняется уникальными значениями. | | Не передан department или jobTitle | В соответствующем одиночном поле сохраняется null. | | Не передан departments или jobTitles | Соответствующая коллекция остаётся пустой. | | Клиент передаёт fullName | В create request поле fullName не описано. Сервер формирует fullName из name + surname. | Ошибки Error responses | HTTP status | Когда возникает | | ------------------------- | ----------------------------------------------------------------------------------- | | 400 Bad Request | Отсутствует хотя бы один required-параметр email, name, surname, gender или active. | | 400 Bad Request | gender не равен Male или Female. | | 400 Bad Request | active не является JSON-boolean значением true или false. | | 401 Unauthorized | Bearer token отсутствует или невалиден. | | 403 Forbidden | Недостаточно прав или token без company context. | | 409 Conflict | Employee с таким email уже существует. | | 500 Internal Server Error | Неожиданная ошибка BFF. | | 503 Service Unavailable | Сбой внутренней интеграции BFF -> back2. | Использование - Создать активного сотрудника с доступом к личному кабинету: active = true. - Создать сотрудника без доступа к личному кабинету: active = false. - Передать несколько департаментов или должностей с определением primary-значения. - Синхронизировать сотрудников из внешней HR-системы. Типичные ошибки Typical integration mistakes | Типичная ошибка | Как правильно | | ----------------------------------------------------- | ---------------------------------------------------------- | | Передавать active как строку "true" или "false" | Передавайте true или false как JSON-boolean. | | Передавать gender в значении, отличном от Male/Female | Используйте только Male или Female. | | Передавать idCompany или hrEmail | Не передавайте эти значения; BFF берёт их из Bearer token. | | Ожидать идемпотентность через Idempotency-Key | В текущей реализации Idempotency-Key не используется. | | Передавать fullName вместо name и surname | Передавайте name и surname; fullName формирует сервер. | FAQ Какие поля обязательны для создания сотрудника? email, name, surname, gender и active. Что делает active = true? Сервер создаёт или синхронизирует связанный пользовательский аккаунт в Keycloak и открывает доступ к личному кабинету. Что делает active = false? Сотрудник создаётся без доступа к личному кабинету, то есть без пользователя в Keycloak. Что будет, если email уже существует? API вернёт 409 Conflict. Нужно ли передавать hrEmail? Нет. BFF берёт hrEmail из Bearer token.

Обновлено Apr 25, 2026

Как частично обновить данные сотрудника через API?

PATCH /v1/employees/{employeeId} обновляет только переданные поля. Body должен содержать хотя бы одно поле. Для доступа нужен scope employees.write. Endpoint | Параметр | Значение | | -------------- | ---------------------------------------------------- | | Method | PATCH | | Path | /v1/employees/{employeeId} | | Base URL | https://smartway.pro/api | | Auth | Bearer token | | Required scope | employees.write | Назначение Endpoint используется для частичного обновления сотрудника в рамках текущего tenant-а. Поле fullName не входит в PATCH-контракт; для изменения ФИО используются name и surname. Предусловия - Клиент должен передать валидный Bearer token. - Token должен содержать company context. - Token должен содержать scope employees.write. - employeeId должен принадлежать сотруднику в рамках текущего tenant-а. - PATCH-body должен содержать хотя бы одно поле. - idCompany и hrEmail не передаются внешним клиентом. Запрос Path parameters | Параметр | Тип | Обязательный | Описание | | ------------ | ------- | ---------------- | -------------- | | employeeId | int64 | да | ID сотрудника. | Body parameters | Поле | Тип | Обязательное | Описание | | ----------- | -------- | ---------------- | ------------------------------------------------------------------------------------- | | email | string | нет | Обновить email. | | name | string | нет | Обновить имя сотрудника. Если поле передано, оно должно содержать непустой текст. | | surname | string | нет | Обновить фамилию сотрудника. Если поле передано, оно должно содержать непустой текст. | | gender | string | нет | Обновить пол. | | department | string | нет | Обновить primary-департамент. | | departments | string[] | нет | Заменить полный набор департаментов. | | jobTitle | string | нет | Обновить primary-должность. | | jobTitles | string[] | нет | Заменить полный набор должностей. | | phone | string | нет | Обновить телефон. | | active | boolean | нет | Обновить признак активности. | curl пример Обновить ФИО, primary-поля, массивы и active curl -X PATCH 'https://smartway.pro/api/v1/employees/4432' \ -H 'Authorization: Bearer <access_token>' \ -H 'Accept: application/json' \ -H 'Content-Type: application/json' \ --data-binary @- <<'JSON' { "name": "Обновленное имя", "surname": "Фамилия", "department": "Управление", "departments": ["КЛ", "Логистика"], "jobTitle": "Старший менеджер", "jobTitles": ["Координатор", "Аналитик"], "active": false } JSON Ответ Успешный ответ: 200 OK. Возвращает обновлённый Employee. { "employeeId": 4432, "candidateId": 10748, "email": "employee@example.com", "fullName": "Обновленное имя Фамилия", "name": "Обновленное имя", "surname": "Фамилия", "gender": "not_specified", "department": "Управление", "departments": [ "КЛ", "Логистика", "Управление" ], "jobTitle": "Старший менеджер", "jobTitles": [ "Аналитик", "Координатор", "Старший менеджер" ], "phone": "+380000000000", "active": false } Поля ответа Employee | Поле | Тип | Описание | | ----------- | -------- | ------------------------------------------------------- | | employeeId | int64 | ID сотрудника. | | candidateId | int64 | ID связанного кандидата. | | email | string | Email сотрудника. | | fullName | string | Полное имя, которое сервер формирует из name + surname. | | name | string | Имя. | | surname | string | Фамилия. | | gender | string | Пол. | | department | string | Основной департамент. | | departments | string[] | Набор департаментов. | | jobTitle | string | Основная должность. | | jobTitles | string[] | Набор должностей. | | phone | string | Телефон. | | active | boolean | Признак активности. | Бизнес-логика - BFF берёт companyId из Bearer token, а не из параметров запроса. - BFF берёт hrEmail из Bearer token. hrEmail равен email пользователя с ролью HRADMIN, который создал или ротировал активный API key компании. - Если активный API key будет ротирован другим HRADMIN, следующие patch-операции автоматически начнут использовать его hrEmail. - PATCH изменяет только те поля, которые переданы в body. - fullName не передаётся в PATCH-body. Сервер формирует fullName из актуальных name + surname. - name и surname можно передавать вместе или отдельно. Если поле передано, оно должно содержать непустой текст. - Текстовые поля поддерживают UTF-8. - Если передан только departments или jobTitles, первый элемент массива становится primary-значением. - Если передано и одиночное поле, и массив, одиночное поле остаётся primary. - Массивы departments и jobTitles в ответе возвращаются в отсортированном виде. - Если новый email уже принадлежит другому employee, API возвращает 409 Conflict. - Если active меняется с false на true, сервер создаёт или повторно синхронизирует связанного Keycloak-пользователя и открывает доступ к личному кабинету. - Если active меняется с true на false, сервер удаляет связанного Keycloak-пользователя и отзывает доступ к личному кабинету. - Если PATCH одновременно меняет active и email, сервер синхронизирует именно аккаунт, который уже был связан с этим employee, а не произвольного пользователя по новому email. Edge cases Edge cases | Сценарий | Поведение API | | -------------------------------------------- | ------------------------------------------------------------------------------ | | PATCH-body пустой | API возвращает 400 Bad Request. | | name или surname переданы пустыми | API возвращает 400 Bad Request. | | fullName передан в PATCH-body | Поле не входит в PATCH-контракт; используйте name и surname. | | Новый email уже принадлежит другому employee | API возвращает 409 Conflict. | | Передан только departments или jobTitles | Первый элемент массива становится primary-значением. | | Передано одиночное поле и массив | Одиночное поле остаётся primary, массив в ответе возвращается отсортированным. | | active меняется с false на true | Сервер создаёт или синхронизирует связанного Keycloak-пользователя. | | active меняется с true на false | Сервер удаляет связанного Keycloak-пользователя. | | active и email меняются одновременно | Синхронизируется аккаунт, уже связанный с этим employee. | Ошибки Error responses | HTTP status | Когда возникает | | ------------------------- | ------------------------------------------------------------------------------------------------------------------- | | 400 Bad Request | Пустой PATCH-body или невалидные значения, включая пустые name / surname. | | 401 Unauthorized | Bearer token отсутствует или невалиден. | | 403 Forbidden | Недостаточно прав или token без company context. | | 404 Not Found | Сотрудник не найден в рамках текущего tenant-а. | | 409 Conflict | Новый email уже занят другим employee или не может быть безопасно использован для синхронизации доступа в Keycloak. | | 500 Internal Server Error | Неожиданная ошибка BFF. | | 503 Service Unavailable | Сбой внутренней интеграции BFF -> back2. | Использование - Обновить контактные данные сотрудника. - Изменить департамент или должность. - Включить доступ к личному кабинету через active = true. - Отозвать доступ к личному кабинету через active = false. - Обновить email с проверкой конфликта. Типичные ошибки Typical integration mistakes | Типичная ошибка | Как правильно | | ----------------------------------------------------- | ----------------------------------------------------------------------- | | Отправлять пустой PATCH-body | Передайте хотя бы одно поле для изменения. | | Передавать fullName | Передавайте name и surname. | | Передавать пустые name или surname | Если поле передано, оно должно содержать непустой текст. | | Ожидать, что изменение active только меняет флаг в БД | active также управляет синхронизацией связанного Keycloak-пользователя. | | Передавать idCompany или hrEmail | Не передавайте эти значения; BFF берёт их из Bearer token. | FAQ Можно ли передать только одно поле в PATCH? Да. Body должен содержать хотя бы одно поле. Можно ли изменить fullName напрямую? Нет. fullName не входит в PATCH-контракт. Используйте name и surname. Что будет, если новый email уже занят? API вернёт 409 Conflict. Что происходит при active = false? Сервер удаляет связанного Keycloak-пользователя и отзывает доступ к личному кабинету. Что происходит, если одновременно изменить active и email? Сервер синхронизирует аккаунт, который уже связан с этим employee.

Обновлено Apr 25, 2026

Как удалить сотрудника через API?

DELETE /v1/employees/{employeeId} удаляет сотрудника в рамках tenant-контекста. Успешный ответ — 204 No Content. Endpoint | Параметр | Значение | | -------------- | ---------------------------------------------------- | | Method | DELETE | | Path | /v1/employees/{employeeId} | | Base URL | https://smartway.pro/api | | Auth | Bearer token | | Required scope | employees.write | Назначение Endpoint используется для удаления сотрудника по employeeId. Операция выполняется в рамках tenant-контекста из Bearer token. Предусловия - Клиент должен передать валидный Bearer token. - Token должен содержать company context. - Token должен содержать scope employees.write. - idCompany не передаётся отдельно. - employeeId должен принадлежать сотруднику в рамках текущего tenant-а. Запрос Path parameters | Параметр | Тип | Обязательный | Описание | | ------------ | ------- | ---------------- | -------------- | | employeeId | int64 | да | ID сотрудника. | curl пример Удалить сотрудника curl -X DELETE 'https://smartway.pro/api/v1/employees/4432' \ -H 'Authorization: Bearer <access_token>' \ -H 'Accept: application/json' Ответ Успешный ответ: 204 No Content. Успешный ответ не содержит body. Поля ответа Delete response | Элемент | Тип | Описание | | ------------- | -------------- | --------------------------- | | HTTP status | 204 No Content | Операция выполнена успешно. | | Response body | отсутствует | Body не возвращается. | Бизнес-логика - BFF берёт companyId из Bearer token, а не из параметров запроса. - Endpoint удаляет сотрудника только в рамках текущего tenant-контекста. - Для доступа нужен scope employees.write. Edge cases Edge cases | Сценарий | Поведение API | | --------------------------------------- | -------------------------------------------------------- | | employeeId не найден в текущем tenant-е | API возвращает 404 Not Found. | | Bearer token без employees.write | API возвращает 403 Forbidden. | | Операция успешна | API возвращает 204 No Content без body. | | Клиент передаёт idCompany | Endpoint не использует idCompany из клиентского запроса. | Ошибки Error responses | HTTP status | Когда возникает | | ------------------------- | ------------------------------------------------ | | 401 Unauthorized | Bearer token отсутствует или невалиден. | | 403 Forbidden | Недостаточно прав или token без company context. | | 404 Not Found | Сотрудник не найден в рамках текущего tenant-а. | | 500 Internal Server Error | Неожиданная ошибка BFF. | | 503 Service Unavailable | Сбой внутренней интеграции BFF -> back2. | Использование - Удалить сотрудника из LMS Smart Way через интеграцию. - Очистить тестовые записи после проверки интеграции. - Убрать сотрудника, который больше не должен находиться в employee dataset. Типичные ошибки Typical integration mistakes | Типичная ошибка | Как правильно | | -------------------------------------- | ------------------------------------------------------------ | | Ожидать JSON в ответе | Успешный ответ — 204 No Content без body. | | Передавать idCompany | Не передавайте idCompany; companyId берётся из Bearer token. | | Использовать token без employees.write | Для DELETE нужен scope employees.write. | FAQ Что возвращает API после успешного удаления? 204 No Content без response body. Нужно ли передавать idCompany? Нет. companyId берётся из Bearer token. Что будет, если employeeId не найден? API вернёт 404 Not Found.

Обновлено Apr 25, 2026