Entity User Service
Overview
The Entity User Service manages users within the system. Each user is linked to an Entity (customer or supplier) and assigned a Role that controls their permissions.
Users can self-register, manage their own profile and password, or be created and managed by admins.
All admin operations require specific permissions. Self-service operations require authentication only.
Endpoints
POST
/api/v1/users/register
Registers a new web user. A new Entity is automatically created — EntityId cannot be supplied.
Authorization:
[AllowAnonymous]— no token required
Request body (RegisterWebUserRequest):
Email(string, required) — must be a valid email, max 250 charsPassword(string, required) — min 8 charactersFirstName(string?, optional)LastName(string?, optional)
Behavior:
- Creates a new Entity automatically
- Registers the user against the current tenant
- Returns
400if email is already in use or tenant is invalid
Response:
201 Created—UserResponse400 Bad Request—{ error: "REGISTRATION_FAILED" }
POST
/api/v1/users/reset-password
Requests a password reset link for the given email.
Authorization:
[AllowAnonymous]— no token required
Request body (ResetPasswordRequest):
Email(string, required)
Behavior:
- Always returns success to prevent email enumeration
- In
DEBUGmode the reset token is returned in the response; in production it would be sent via email
Response:
200 OK—{ message: "If the email exists, a reset link has been sent." }
POST
/api/v1/users/reset-password/confirm
Confirms a password reset using the token issued by reset-password.
Authorization:
[AllowAnonymous]— no token required
Request body (ConfirmResetPasswordRequest):
Token(string, required)NewPassword(string, required)
Response:
200 OK—{ message: "Password has been reset successfully." }400 Bad Request—{ error: "INVALID_TOKEN" }
GET
/api/v1/users/me
Returns the current authenticated user's profile.
Authorization:
- Requires Bearer Token
- Permission:
FullRead
Response:
200 OK—UserResponse401 Unauthorized— not authenticated404 Not Found— user not found
PUT
/api/v1/users/me
Updates the current authenticated user's profile.
Authorization:
- Requires Bearer Token
- Permission:
FullManage
Request body (UpdateUserRequest):
FirstName(string?, optional)LastName(string?, optional)Department(string?, optional)SubDepartment(string?, optional)
Response:
200 OK—UserResponse401 Unauthorized404 Not Found
POST
/api/v1/users/me/change-password
Changes the current authenticated user's password.
Authorization:
- Requires Bearer Token
- Permission:
FullManage
Request body (ChangePasswordRequest):
CurrentPassword(string, required)NewPassword(string, required)
Response:
200 OK—{ message: "Password changed successfully." }400 Bad Request—{ error: "INVALID_PASSWORD" }— current password is incorrect
GET
/api/v1/users
Returns a paginated list of all users.
Authorization:
- Requires Bearer Token
- Permission:
users:read
Query parameters:
page(int, default: 1)pageSize(int, default: 50, max: 200)search(string?, optional) — search by name or emailisActive(bool?, optional) — filter by active status
Response:
200 OK—UserListResponse
GET
/api/v1/users/{id}
Returns a single user by their ID.
Authorization:
- Requires Bearer Token
- Permission:
users:read
Route parameters:
id(long, required)
Response:
200 OK—UserResponse404 Not Found
POST
/api/v1/users
Creates a new user and assigns them to an existing entity with a role.
Authorization:
- Requires Bearer Token
- Permission:
users:write
Request body (CreateUserRequest):
Email(string, required) — valid email, max 250 charsPassword(string, required) — min 8 charactersFirstName(string?, optional)LastName(string?, optional)EntityId(long, required) — must be an existing entityUserTypeId(short?, optional)Department(string?, optional)SubDepartment(string?, optional)RoleCode(string, required) — must be a valid roleIsActive(bool, default: true)
Response:
201 Created—UserResponse400 Bad Request—{ error: "CREATE_FAILED" }— email exists, entity not found, or invalid role
PUT
/api/v1/users/{id}
Updates a user's details (admin).
Authorization:
- Requires Bearer Token
- Permission:
users:write
Route parameters:
id(long, required)
Request body (AdminUpdateUserRequest):
Email(string?, optional)FirstName(string?, optional)LastName(string?, optional)EntityId(long?, optional)UserTypeId(short?, optional)Department(string?, optional)SubDepartment(string?, optional)RoleCode(string?, optional)IsActive(bool?, optional)
Response:
200 OK—UserResponse400 Bad Request—{ error: "UPDATE_FAILED" }
POST
/api/v1/users/{id}/reset-password
Admin resets a user's password directly.
Authorization:
- Requires Bearer Token
- Permission:
users:manage
Route parameters:
id(long, required)
Request body (AdminResetPasswordRequest):
NewPassword(string, required)
Response:
200 OK—{ message: "Password has been reset. User will need to log in again." }404 Not Found
POST
/api/v1/users/{id}/deactivate
Deactivates a user. Cannot deactivate your own account.
Authorization:
- Requires Bearer Token
- Permission:
users:manage
Route parameters:
id(long, required)
Response:
200 OK—{ message: "User has been deactivated." }400 Bad Request—{ error: "CANNOT_DEACTIVATE_SELF" }404 Not Found
DELETE
/api/v1/users/{id}
Permanently deletes a user. Cannot delete your own account.
Authorization:
- Requires Bearer Token
- Permission:
users:manage
Route parameters:
id(long, required)
Response:
200 OK—{ message: "User has been deleted." }400 Bad Request—{ error: "CANNOT_DELETE_SELF" }404 Not Found
Models
UserResponse
Returned by all read/create/update operations.
Fields:
Id (type: long)- internal user identifierUserGuid (type: Guid)- unique user identifier (used in JWT claims)Email (type: string?)- user email addressFirstName (type: string?)- first nameLastName (type: string?)- last nameIsActive (type: bool)- active flagEntityId (type: long)- associated entity identifierEntityName (type: string?)- resolved entity nameUserTypeId (type: short?)- user type classificationDepartment (type: string?)- departmentSubDepartment (type: string?)- sub-departmentCreatedAt (type: DateTime)- account creation timestampRoleCode (type: string?)- assigned role codeRoleLabel (type: string?)- resolved role display name
UserListResponse
Returned by GET /api/v1/users.
Fields:
Users (type: List<UserResponse>)- paged user listTotalCount (type: int)- total matching recordsPage (type: int)- current pagePageSize (type: int)- page size
Notes
- All admin endpoints require specific permissions (
users:read,users:write,users:manage) - Self-service endpoints (
/me) require authentication only - Public endpoints (
register,reset-password) are anonymous - A user cannot deactivate or delete their own account
- Email must be unique per tenant
RoleCodemust match a valid role defined in the system