The standard login flow is the primary authentication path for back-office users — supervisors, administrators, and any operator who logs in through the web interface. The client submits an email address and password; Dragon Guard verifies the BCrypt hash, checks that the user’s tenant is active, and returns a signed JWT along with user and company metadata.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/CodexaCP/DG_BACK/llms.txt
Use this file to discover all available pages before exploring further.
POST /api/auth/login
Authenticates a user with their email address and password. Returns a JWT token and session metadata on success.Request body
The user’s email address. Must match an existing
auth.Users record.The user’s plaintext password. Verified against the BCrypt hash stored in
auth.Users.PasswordHash.Set to
true when the login request originates from a handheld device. When true and a deviceId is provided, the device is validated and its last-seen metadata is updated as part of the login flow.Device identifier (typically a MAC address). Required when
isHandheld is true. The value is normalized to uppercase colon-separated format (e.g. AA:BB:CC:DD:EE:FF) before lookup.Human-readable label for the device (e.g.
"Scanner-01"). When supplied alongside deviceId, it updates the DeviceName field on the device record. Optional.Response fields
Signed HMAC SHA-256 JWT. Pass this value as
Authorization: Bearer <token> on subsequent requests.The authenticated user’s unique identifier (
auth.Users.Id).The authenticated user’s email address.
The authenticated user’s display name.
true when the user holds the global SUPERADMIN_SUPREMO role. SUPERADMIN_SUPREMO tokens do not contain company_access claims.true when the user is required to change their password before proceeding. Newly registered users always have this flag set.List of company/role pairs the user can access. Each entry contains:
companyId(UUID) — the tenant identifierroleCode(string) — the role assigned in that tenant (e.g.OPERATOR,ADMIN)
Example
Error responses
| Status | Body / messageKey | Cause |
|---|---|---|
400 | EMAIL_AND_PASSWORD_REQUIRED | email or password is missing or blank. |
401 | USER_NOT_FOUND | No auth.Users record matches the supplied email. |
401 | INVALID_USER | The matched user record has no stored password hash (account not fully initialised). |
401 | INVALID_PASSWORD | The password does not match the stored BCrypt hash. |
401 | NO_ACTIVE_COMPANY_AVAILABLE | isHandheld is true but the user has no active company assignment. |
402 | plans.deviceLimitExceeded | The tenant’s active device count exceeds the plan’s deviceLimit. |
403 | auth.companyInactive | The user’s tenant exists but IsActive = false or Status ≠ "Active". |
403 | plans.deviceNotAuthorized | isHandheld is true but the device key is not pre-authorized for the tenant. |
403 | plans.deviceInactive | The device record exists but IsActive = false. |
409 | auth.userAssignedToOtherTenant | The user record is linked to more than one tenant — data must be corrected by an admin. |
503 | LOGIN_TEMPORARILY_UNAVAILABLE | An unexpected server error occurred during login. Retry with exponential back-off. |
POST /api/auth/register
Self-service registration endpoint. Creates a new user (or assigns an existing user to a company) with the defaultOPERATOR role. Intended for handheld and warehouse operator onboarding.
Request body
The new user’s email address. Must satisfy the tenant’s
UserEmailDomain restriction when one is configured (e.g. only @atp.com.py addresses accepted).Plaintext password for the new account. Must satisfy the password policy (see below).
The user’s display name.
The tenant to register the user in. When omitted, the first active company returned by
/api/auth/registration-options is used.Password policy
Passwords must meet all of the following requirements:- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one digit
- At least one special character (non-alphanumeric)
Error responses
| Status | Body / messageKey | Cause |
|---|---|---|
400 | PASSWORD_POLICY_NOT_MET | The supplied password does not satisfy all policy requirements. |
400 | MISSING_REQUIRED_FIELDS | One or more of email, password, or fullName is blank. |
409 | auth.userAlreadyExistsInTenant | A user with this email is already assigned to the specified tenant. |
409 | auth.userAssignedToOtherTenant | The email belongs to a user already assigned to a different tenant. |
POST /api/auth/change-password
Changes the password for the currently authenticated user. Requires a valid Bearer token.This endpoint only works for accounts with
authProvider = DragonGuardLocal. Delegated handheld accounts authenticated through GrupoMAS receive 400 auth.externalPasswordManaged because password authority remains in the MAS system.Request body
The user’s current plaintext password, used to re-verify identity before the change is applied.
The desired new password. Must satisfy the same password policy as registration (min 8 chars, upper, lower, digit, special character).
Example
Error responses
| Status | Body / messageKey | Cause |
|---|---|---|
400 | CURRENT_PASSWORD_INVALID | The supplied currentPassword does not match the stored hash. |
400 | PASSWORD_POLICY_NOT_MET | The newPassword does not satisfy policy requirements. |
400 | auth.externalPasswordManaged | Account uses GrupoMAS delegated auth; password is managed by MAS. |
401 | INVALID_SESSION | The token does not contain a valid userId or email claim. |
GET /api/auth/registration-options
Returns the data needed to populate a self-registration form: the list of active companies available for selection and the default role code that will be assigned to new registrations.Response
GET /api/auth/test
Verifies that the caller’s JWT is valid and returns the key claims resolved from the token. Useful for debugging authentication issues and confirming which company context, role, and company access claims the server sees. Requires a valid Bearer token ([Authorize] — no specific role required).
Response
Example
Error responses
| Status | Cause |
|---|---|
401 | No token supplied or the token is invalid/expired. |