User login


Request description

Endpoint: /users/login

Method: POST

{
  "Content-Type": "application/json"
}

Payload example

{
  "email": "mock@mock.com",
  "password": "mock-password"
}

Payload structure

interface ILoginPayload {
  email: string; //Email related to the user who performs the authentication
  password: string; //Password related to the user who performs the authentication
}

Responses

Authentication results are always returned with status 200. Check the isSuccess field to know whether the login succeeded. Only malformed requests return 400.

Correct response

Successful authentication

Describe a successful login action

200

Response body example:

{
  "isSuccess": true,
  "accessToken": "mock-access-token",
  "accounts": [
    {
      "id": "mock-organization-id~mock-user-id",
      "userId": "mock-user-id",
      "organizationId": "mock-organization-id",
      "userType": "ORGANIZATION_OWNER",
      "organizationName": "mock-organization-name",
      "isSelected": "true",
      "groupId": "mock-group-id",
      "companyStatus": "ACTIVE",
      "customSubdomain": "mock-custom-subdomain",
      "isMandatoryMFA": false
    }
  ],
  "userId": "mock-user-id",
  "fullName": "Mock User Name"
}
Response structure:
interface ILoginResponse {
  isSuccess: boolean;
  accessToken?: string;
  accounts?: IUserAccount[];
  userId?: string;
  fullName?: string;
}

interface IUserAccount {
  id: string;                   // Account identifier (organizationId~userId)
  userId: string;               // Unique user identifier
  organizationId: string;       // Organization identifier. Use it in Select account
  userType: UserType;           // User role in this organization
  organizationName: string;     // Organization name
  isSelected: "true" | "false"; // Whether this is the selected account. Sent as a string
  groupId: string;              // Group of the user in this organization
  companyStatus?: string;       // Organization status, e.g. "ACTIVE"
  customSubdomain?: string;     // Only present when the organization has a custom subdomain
  isMandatoryMFA: boolean;      // Whether the organization requires multi-factor authentication
}

type UserType = "ORGANIZATION_OWNER" | "ORGANIZATION_ADMIN" | "REGULAR";
Description: the account marked with isSelected: "true" is the organization the access token works with. To work with another organization, use Select account.


Additional authentication step required

Describe a login that needs an extra step before returning an access token

200

Response structure

type AuthenticationChallengeResponse = {
  isSuccess: true;
  isMFARequired?: true;          // Present when the user has multi-factor authentication enabled
  isNewPasswordRequired?: true;  // Present when the user must set a new password
  challengeName: "SOFTWARE_TOKEN_MFA" | "NEW_PASSWORD_REQUIRED";
  session: string;
  userId: string;
  email: string;
};
Description: no accessToken is returned. Users with multi-factor authentication enabled, or who must change their password, cannot be used to consume the Management API. Use a user without these requirements, or complete the pending step in the administration console first.


Wrong Authentication

Describe an unsuccessful login action

200

Response body example:

{
  "isSuccess": false,
  "errorMessage": "Invalid authentication",
  "errorType": "unauthorized",
  "remainingAttempts": 4
}
Response structure
type AuthenticationResponseType = {
  isSuccess: boolean,         // Specifies the authentication status
  errorMessage: string,       // Specifies the error message
  errorType: ErrorType,       // Specifies the error type
  remainingAttempts?: number  // Attempts left before the user is blocked
}

enum ErrorType = {
  UNAUTHORIZED = "unauthorized",
  PASSWORD_ATTEMPTS_EXCEEDED = "passwordAttemptsExceeded"
}
Description: remainingAttempts is only returned when the organization limits the number of failed login attempts. When the limit is reached the user is blocked and the response returns errorType: "passwordAttemptsExceeded". A blocked user must be unblocked from the administration console.

Additional notes:
1. The accessToken has a limited lifetime. Read its exp claim to know when it expires and authenticate again before that moment.
2. It must be ensured that the access credentials used belong to a user who is ready to use the platform.
3. You must ensure that the credentials belong to a user with the Organization Owner or Organization Admin role.
4. Every failed attempt counts towards the user's lockout limit. Do not retry automatically with the same credentials.

Wrong responses

Bad request

Describe an invalid request

400

Response structure

type AuthenticationResponseType = {
  isSuccess: boolean, // Specifies the authentication status
  errorMessage: string, // Specifies the error message
  errorType: LoginErrorType // Specifies the error type
}

enum LoginErrorType = {
  MISSING_REQUIRED_FIELDS = "missingRequiredFields", // email or password missing
  INVALID_REQUEST_FORMAT = "invalidRequestFormat"    // body is not valid JSON
}