Users are the operators of a tenant. Everything here lives on UsersController, mounted as @Controller(['profile', 'user']) — so every path below also answers under /user/….
Password sign-in
/profile/signinNo authAlso /profile/user/signin, /user/signin, /user/user/signin.
{ "email": "[email protected]", "password": "…" }Requires the orgid header. Four possible 200 responses — see Sign-in outcomes. Only one contains a token.
Bad credentials are 400 Invalid username or password, recorded as a failed login activity. A blocked device fingerprint is 403 regardless of credentials.
Temporary passwords
A user signing in with a temporary password — stored hashed in resetToken alongside a temporaryPassword flag — gets no session:
{ "requiresPasswordChange": true, "message": "Temporary password used. Please set a new password.", "userId": "…", "email": "…" }POS passcode and NFC
/profile/signin/passcodeNo authFast sign-in for point-of-sale, keyed on the employee id.
{ "employeeId": "E-1042", "pin": "482913", "cardUid": "04A2B3C4D5" }| Field | Type | Description |
|---|---|---|
employeeId required | string | The employee id. An NFC card carries only this value. |
pin | string | Six digits. Required or not depending on the org's passcode-vs-instant setting. |
cardUid | string | The card's hardware UID when signing in by tap. Validated against the registered card list. |
| This path deliberately skips the 2FA and new-device challenges — a shared terminal would otherwise be unusable. |
Managing the credentials:
| Action | Endpoint |
|---|---|
Set or change a passcode, link an employeeId | POST /profile/…/passcode (set) |
| Remove passcode login | remove-passcode handler |
| Register / revoke an NFC card | card registry handlers |
A user may always manage their own quick-login credentials. Doing it for someone else requires RootSystem, RootAdmin, ConfigAdmin, System or Owner; otherwise 403.
Session
/profile/whoamiJWT/profile/who-isJWT/profileJWT/profile/signoutJWT/profile/user/refreshJWT/profile/session-accessJWT/profile/system-orgsJWTInvitations
Users are invited, not self-registered.
/profile/user/invite/sendJWT/profile/user/invite/resend/:invitationIdJWT/profile/user/invite/validateNo auth/profile/user/invite/completeNo authInvitations are user_invitation records. validate confirms a token before showing the form; complete sets the password and activates the account.
Profiles
/profile/user/profile/:emailOrUsernameJWT/profile/user/:userId/metaJWT/profile/user/delete/:emailOrUsernameJWT/profile/user/selfJWTReading or writing your own profile bypasses role checks — JwtAuthGuard compares the target record's sk with the caller's before any decorator is consulted.
/profile/user/self is self-service account deletion, distinct from an admin deleting someone.
Magic links and codes
/profile/user/magic-linkNo auth/profile/user/magic-link/redirectNo auth/profile/magic-linkNo auth/profile/magic-link/redirectNo auth/profile/code/:emailNo authA magic-link token is a short-lived JWT whose payload is { clientHost, email, expires } — signed the same way as a session token, so it verifies through the same machinery.
Shared-site access
/profile/user/shared-site-auth/:tokenNo authExchanges a share token for access — the share block on BaseModel, with its optional passcode and expiry.
Application registration
For client apps that need their own identity:
/profile/app/registerNo auth/profile/app/keyJWT/profile/validate-app-keyNo authRegistration returns { appConfig, token }. Backed by the client_app datatype.
Global login
/profile/global-loginNo authSigns in across orgs rather than against one tenant. Pair with GET /repository/org/user/:email to build an org switcher.
Guest access
/profile/guest/authNo authIssues a token for an anonymous guest customer — enough to hold a cart or a draft booking before the visitor commits to an account.