Base URL:/api/Users Authentication: Most endpoints require a valid JWT Bearer token. Exceptions are noted per endpoint. Header:Authorization: Bearer <token>
Validates user credentials (supports local and LDAP), issues a JWT token valid for 7 days, and records login history. The token payload includes user roles and permission claims.
Property
Value
Method
POST
Endpoint
/api/Users/authenticate
Auth
None (anonymous)
Body
application/json
Request Body (Authenticate)
Field
Type
Required
Description
Email
string
Yes
Username or email address
Password
string
Yes
Account password
RememberMe
bool
No
Whether to persist the sign-in session
Domain
string
No
LDAP/AD domain for domain authentication
Response Body (200 OK)
Field
Type
Description
Id
string
User ID (GUID)
Username
string
Login username
FirstName
string
User’s first name
LastName
string
User’s last name
Avatar
string
Full URL to the user’s avatar image
UserSettings
object
User preference settings (mapped from UserSettingJson)
One claim per permission granted through the user’s roles
Responses
Status
Description
200 OK
Authentication successful — returns user info and JWT token
401 Unauthorized
Invalid username/password or account locked out
Note: Failed login attempts are recorded in login history. After a threshold of failures the account may be locked out (ASP.NET Identity lockout policy).
2. Refresh Token
Re-issues a fresh JWT token for the currently authenticated user without requiring credentials. Useful for extending a session before expiry. The new token is valid for 7 days from the time of the call.
Returns the members of a specific group (by group ID), or all technicians if no group ID is provided.
Property
Value
Method
GET
Endpoint
/api/Users/GroupUsers/{id?}
Auth
JWT Bearer required
Path Parameters
Parameter
Type
Required
Description
id
int
No
Group ID. If omitted, returns all users in the Technician role.
Responses
Status
Description
200 OK
Returns an array of ApplicationUser objects belonging to the group, or all technicians if no ID provided
4. Get Technicians
Returns all users in the Technician role.
Property
Value
Method
GET
Endpoint
/api/Users/technicians
Auth
None (anonymous)
Responses
Status
Description
200 OK
Returns an array of ApplicationUser objects in the Technician role
5. Get All Users
Returns all active and visible users who are not in the Member or System roles.
Property
Value
Method
GET
Endpoint
/api/Users
Auth
None (anonymous)
Filters Applied (server-side)
Status == Active
IsVisible == true
Role is not Member or System
Responses
Status
Description
200 OK
Returns a deduplicated array of ApplicationUser objects
6. Search Users
Full-text user search with optional group, department, and unassigned filters. Returns results formatted for Select2 dropdowns, including resolved avatar URLs and role lists.
Property
Value
Method
GET
Endpoint
/api/Users/SearchUsers
Auth
None (anonymous)
Query Parameters
Parameter
Type
Required
Default
Description
term
string
No
""
Search keyword(s). Multi-word terms are split by spaces and ANDed. Matches against email, first name, and last name.
groupId
int?
No
null
If provided, restricts results to members of the specified group
unassigned
bool
No
false
If true and no search term is given, prepends an “Unassigned” option to the result list
departmentId
int?
No
null
If provided (and groupId is null), restricts results to users in the specified department
Search Behaviour
With groupId: Searches within group members only; matches email OR (first name AND last name) for each keyword.
Without groupId: Searches all active, visible non-Member/non-System users; applies department filter if departmentId is given.
Multi-keyword search: each keyword must appear somewhere (AND logic within a field group, OR between field groups).
Paginated user search designed for dual listbox controls. Returns active, visible users who are not already assigned to the specified site. Supports multi-keyword search on email, username, first name, and last name.
Property
Value
Method
GET
Endpoint
/api/Users/DualSearch
Auth
JWT Bearer required
Query Parameters
Parameter
Type
Required
Default
Description
siteId
int
Yes
—
Excludes users already assigned to this site
search
string
No
""
Search keyword(s). Splits by spaces; each keyword ANDed. Matches email/username OR first/last name.
page
int
No
1
Page number (1-based; minimum 1)
pageSize
int
No
50
Items per page (minimum 1)
Response Body (200 OK)
{"items":[{"id":"string","text":"John Doe [johndoe]"}],"hasMore":true,"totalCount":120,"page":1,"pageSize":50}
Field
Type
Description
items
array
Page of matching users
id
string
User ID
text
string
Display label: "DisplayName [username]"
hasMore
bool
Whether more pages are available
totalCount
int
Total number of matching users
page
int
Current page number
pageSize
int
Items per page used for this response
8. Forgot Password
Sends a password reset email to the specified address if a confirmed account exists. Intentionally returns a generic success message regardless of whether the email is registered (to prevent user enumeration).
"If your email is registered, you will receive a password reset link shortly." — returned even if the email is not found (prevents user enumeration)
200 OK
"Successful. Please check your email to reset your password..." — returned when reset email is dispatched
400 Bad Request
Email value is empty or whitespace
Note: Email delivery failures are logged server-side but do not affect the HTTP response. The endpoint always returns 200 OK once validation passes.
Common Error Responses
Status
Description
401 Unauthorized
Missing or invalid JWT token (on protected endpoints)
400 Bad Request
Invalid or missing required input
Notes
The JWT token expires 7 days after issuance. Use the Refresh Token endpoint to renew it without re-entering credentials.
Permission claims (permission) are embedded in the token and derived from the role(s) assigned to the user. No separate permissions endpoint is needed.
Avatar URLs returned by Search and Authenticate endpoints are fully absolute (scheme + host + path).
User search endpoints (Search Users and Dual Search) use AND logic across keywords and OR logic between field groups (email/username vs. name).