PxUser-Frontend Documentation

Table of Contents

  1. Prerequisites
  2. Class Config
  3. Widgets-Types
    1. Password Forgot + Resend Activation Mail
    2. Password Set
    3. Password Set and Login
    4. Password Set and Login with OIDC
    5. Activate User
    6. Login
    7. Activate user With Activation Code
    8. Activate User and Login
    9. Activate User and Login with OIDC
    10. Password set by forgot password code
    11. Password set by forgot password code and login
    12. Password Set by Forgot-Password-Code and Login with OIDC
    13. Confirm New Email
    14. Alternative Email
    15. Alternative Email (standalone)
    16. Configure an External Identity Provider
    17. Single Sign-On
    18. Open ID Connect
    19. Standalone Single Sign-On
    20. Account Linking
    21. MFA Setup
    22. Change Password
    23. Security notes
  4. Errors reference
    1. How errors reach your application
    2. Widget error payload
    3. User-frontend errors
    4. API error codes (pass-through)

How to embed PxUser widgets into a website

Prerequisites

  1. Embed <script src="https://user-frontend.api.pl-x.cloud/js/widget.js"></script> in any page you want to use these widgets.
  2. Add HTML-Elements with unique IDs for each widget. (e.g. <div id="pxUserPasswordForgot"></div>)

Class Config

Our config consists of two parts. There is the main class which contains general settings for a product, and then there are individual methods for each widget which accept additional config.

let pxUserFrontend = new PxModUser({
    stage: 'prod',
    mode: 'integrated',
    domain: 'px-user-frontend-preview',
    tenant: 'demo',
    cssUrl: 'https://www.example.com/styles.css',
    language: 'de',
    showSpinner: false
});
Parameter Description
stage required
The stage your site runs on. Defines wether widgets should be served from testing or production environment.
Available values: preprod / prod.
mode optional
Selects which widget domain to use for a given stage.
Available values: integrated / standalone.
Default: integrated.
domain required
Domain code which is provided by VNR for every product (e.g. px-user-frontend-preview).
tenant required
Tenant code which is provided by VNR for every product (e.g. demo).
cssUrl Absolute path to a CSS file to add custom styling to all widgets.
language Default language for messages and labels.
Available values: en / de.
showSpinner optional
When true, improves loading feedback in two ways: (1) Host page (container element): a full-area overlay with a centered spinner is shown while the widget iframe is loading (e.g. OIDC/SSO login initial request, token exchange, client validation). It is removed when the iframe reports its height or when a redirect is triggered. (2) Inside the iframe: a small spinner inside each submit button during authentication-related form submissions. Default: false. Can be set at class level (applies to all widgets) or at method level per widget; method-level overrides class-level. Customize button spinners via .px-spinner-inline in your cssUrl stylesheet; the host overlay uses .px-widget-loading-overlay and .px-widget-loading-spinner.

This applies to all widgets

After clicking a submit button, the button will automatically be disabled as well as the class .loading is added for individual styling. It will be removed once the server sends a response. When showSpinner: true is set (either in the class config or in the widget method config), a small rotating spinner appears inside the button before its label during submission and is removed when the request completes. While the iframe document is still loading, the host-page container may show a full-area loading overlay (see showSpinner above).

Widgets-Types

Password Forgot + Resend Activation Mail

Click to expand
pxUserFrontend.showPasswordForgotForm({
    containerElement: 'pxUserPasswordForgot',
    fallbackTargetUrl: 'https://www.example.com/password-forgot',
    fallbackButtonText: 'Send password reset email!',
    labels: {
        buttonText: 'Send password reset email!',
        email: 'Email-address'
    },
    products: ['sap', 'dam', 'vid'],
    onSuccess: (data) => {
        doSomethingWith(data)
    },
    onError: (error) => {
        doSomethingWith(error)
    }
});
Parameter Description
containerElement required
HTML-Element where this widget will be rendered in.
fallbackTargetUrl required
If there are errors in JS code, this is a fallback where form contents are sent to with a POST request.
fallbackButtonText required
If there are errors in JS code, this is the text for the submit button .
labels optional Labels for button and form elements.
Default: { buttonText: 'Send link', email: 'Email address' }
products optional
An array of products for which the password reset is requested.
Default: null
onSuccess Function which will be called if form is submitted successfully.
Returns JSON object.
e.g. { success: true, code: 200, http_code: 200, message: "OK", response: {} }
onError Function which will be called if there is an error when submitting the form.
Returns JSON object.
e.g. { success: false, code: 403, http_code: 403, message: "CSRF token mismatch." }

Password Set

Click to expand
pxUserFrontend.showPasswordSetForm({
    token: 'abc123',
    containerElement: 'pxUserPasswordSet',
    showPasswordRules: false,
    fallbackTargetUrl: 'https://www.example.com/password-set',
    fallbackButtonText: 'Reset Password!',
    labels: {
        buttonText: 'Reset Password!',
        passwordOne: 'Password',
        passwordTwo: 'Password again'
    },
    icons: {
        togglePassword: {
            passwordOne: true,
            passwordTwo: true
        }
    },
    onSuccess: (data) => {
        doSomethingWith(data)
    },
    onError: (error) => {
        doSomethingWith(error)
    }
});
Parameter Description
token required
Security-Token from URL.
containerElement required
HTML-Element where this widget will be rendered in.
showPasswordRules optional
Show password rules under the password field directly by typing.
Default: false
fallbackTargetUrl required
If there are errors in JS code, this is a fallback where form contents are sent to with a POST request.
fallbackButtonText required
If there are errors in JS code, this is the text for the submit button.
labels optional Labels for button and form elements.
Default: { buttonText: 'Set new password', passwordOne: 'Password', passwordTwo: 'Password again' }
icons.togglePassword optional Icons and onclick events for toggle (show/hide) the password.
Default: {passwordOne: true, passwordTwo: true}. The default icon is eye.
E.g. use custom icon (bootstrap): {passwordOne: 'bi bi-eyeglasses', passwordTwo: true}
onSuccess Function which will be called if form is submitted successfully.
Returns JSON object.
e.g. { success: true, code: 200, http_code: 200, message: "Success", response: { passed: true } }
onError Function which will be called if there is an error when submitting the form.
Returns JSON object.
e.g. { "success": false, "code": 1200, "http_code": 401, "message": "Unauthorized", "response": null, "metadata": [] }

Password Set and Login

Click to expand

Same flow as Password Set (token from the reset link), but after setting the password the user is logged in: the API returns access_token and refresh_token in data.response (see Activate User and Login).

pxUserFrontend.showPasswordSetAndLoginForm({
    token: 'abc123',
    containerElement: 'pxUserPasswordSetAndLogin',
    showPasswordRules: false,
    fallbackTargetUrl: 'https://www.example.com/password-set-and-login',
    fallbackButtonText: 'Set password and login',
    labels: {
        buttonText: 'Set password and login',
        passwordOne: 'Password',
        passwordTwo: 'Password again',
        mfaInitTitle: 'MFA Setup',
        mfaInitMessage: 'Scan the QR code with your authenticator app or enter the secret manually.',
        mfaInitCodeLabel: 'Token:',
        mfaInitButtonText: 'Set up',
        mfaVerifyTitle: 'MFA Verify',
        mfaVerifyCodeLabel: 'Enter the code from your authenticator app.',
        mfaVerifyButtonText: 'Verify',
        mfaEnabledTitle: 'MFA Enabled',
        mfaEnabledMessage: 'Multi-factor authentication has been enabled.',
        mfaEnabledButtonText: 'Continue',
    },
    icons: {
        togglePassword: {
            passwordOne: true,
            passwordTwo: true
        }
    },
    onSuccess: (data) => {
        doSomethingWith(data)
    },
    onError: (error) => {
        doSomethingWith(error)
    },
    onResetError: (data) => {
        // credentials accepted, additional step required (e.g. MFA) before login completes
        // host should reset any previous onError UI
        clearLoginErrorBanner()
    }
});
Parameter Description
token required
Security-Token from URL.
containerElement required
HTML-Element where this widget will be rendered in.
showPasswordRules optional
Show password rules under the password field directly by typing.
Default: false
fallbackTargetUrl required
If there are errors in JS code, this is a fallback where form contents are sent to with a POST request.
fallbackButtonText required
If there are errors in JS code, this is the text for the submit button.
labels optional Labels for button and form elements.
Default: { buttonText: 'Set new password and login', passwordOne: 'Password', passwordTwo: 'Password again' }.
When MFA is triggered after setting the password, this widget forwards these labels to the internal MFA screens: mfaInitTitle, mfaInitMessage, mfaInitCodeLabel, mfaInitButtonText, mfaVerifyTitle, mfaVerifyCodeLabel, mfaVerifyButtonText, mfaEnabledTitle, mfaEnabledMessage, mfaEnabledButtonText.
icons.togglePassword optional Icons and onclick events for toggle (show/hide) the password.
Default: {passwordOne: true, passwordTwo: true}. The default icon is eye.
E.g. use custom icon (bootstrap): {passwordOne: 'bi bi-eyeglasses', passwordTwo: true}
onSuccess Function which will be called if form is submitted successfully.
Returns JSON object.
e.g. { success: true, code: 200, http_code: 200, message: "OK", response: { access_token: 'abc', access_token_lifetime_minutes: 120, access_token_expiration_utc: '2021-10-07T13:15:39.120677Z', refresh_token: 'xyz', refresh_token_lifetime_minutes: 43200, refresh_token_expiration_utc: '2021-11-06T11:15:39.121160Z' } }
onError Function which will be called if there is an error when submitting the form.
Returns JSON object.
e.g. { "success": false, "code": 1200, "http_code": 401, "message": "Unauthorized", "response": null, "metadata": [] }
onResetError optional Use this callback to reset any error UI previously shown via onError. Fires when the server requires an additional step (e.g. MFA) after valid credentials but before onSuccess, so a stale error banner from a previous attempt does not stay visible during the challenge.
Returns JSON object.
e.g. { "success": true, "code": 200, "http_code": 200, "message": "OK", "response": { "challenge": "mfa/init", "challenge_token": "..." } }

Notes:

  • MFA init, verify, and enable screens are internal challenge screens. Product integrations should configure their labels on showPasswordSetAndLoginForm; they are not exposed as separate public widget methods.

Password Set and Login with OIDC

Click to expand

OIDC-compatible variant of Password Set and Login. Instead of passing tokens to onSuccess, after successfully setting the password the user is logged in and the browser is redirected to the given redirect_uri with an OIDC authorization code (?code=...&state=...&codeType=auth_code&tenant=...&domain=...). The product exchanges that code at the OIDC token endpoint (PKCE required).

pxUserFrontend.showPasswordSetAndLoginWithOidcForm({
    token: 'abc123',
    containerElement: 'pxUserPasswordSetAndLoginWithOidc',
    client_id: 'your-client-id',
    redirect_uri: 'https://product.example/sso/callback',
    state: 'opaque-product-state',
    scope: 'openid',
    code_challenge: 'dEjftdeZ4C...hbUJUXk',
    code_challenge_method: 'S256',
    onError: (error) => { ... },
});
Parameter Description
token required
Security-Token from URL.
containerElement required
ID of the element the widget iframe is rendered into.
client_id required
Registered OIDC client id of the product.
redirect_uri required
Registered redirect URI; receives code + state after success.
state strongly recommended
Opaque value returned unchanged on the redirect. Always send a unique, unguessable value and verify it on the callback to protect against CSRF.
scope required
Must contain openid.
code_challenge required
PKCE code challenge (S256 of your code_verifier).
code_challenge_method required
Only S256 is supported.

Notes:

  • onSuccess is not used to deliver tokens — after successfully setting the password the user is logged in and the top-level page is redirected to redirect_uri.
  • MFA challenges are handled inside the widget, exactly like the classic variant.
  • All other parameters (labels, icons, showPasswordRules, fallbackTargetUrl, ...) work as in Password Set and Login.

Activate User

Click to expand
pxUserFrontend.showActivateUserForm({
    token: 'abc123',
    containerElement: 'pxUserActivateUser',
    showPasswordRules: false,
    fallbackTargetUrl: 'https://www.example.com/user-activate',
    fallbackButtonText: 'Set Password!',
    labels: {
        buttonText: 'Set Password!',
        passwordOne: 'Password',
        passwordTwo: 'Activate user'
    },
    icons: {
        togglePassword: {
            passwordOne: true,
            passwordTwo: true
        }
    },
    onSuccess: (data) => {
        doSomethingWith(data)
    },
    onError: (error) => {
        doSomethingWith(error)
    }
});
Parameter Description
token required
Security-Token from URL.
containerElement required
HTML-Element where this widget will be rendered in.
showPasswordRules optional
Show password rules under the password field directly by typing.
Default: false
fallbackTargetUrl required
If there are errors in JS code, this is a fallback where form contents are sent to with a POST request.
fallbackButtonText required
If there are errors in JS code, this is the text for the submit button.
labels optional Labels for button and form elements.
Default: { buttonText: 'Activate user', passwordOne: 'Password', passwordTwo: 'Password again' }
icons.togglePassword optional Icons and onclick events for toggle (show/hide) the password.
Default: {passwordOne: true, passwordTwo: true}. The default icon is eye.
E.g. use custom icon (bootstrap): {passwordOne: 'bi bi-eyeglasses', passwordTwo: true}
onSuccess Function which will be called if form is submitted successfully.
Returns JSON object.
e.g. { success: true, code: 200, http_code: 200, message: "Success", response: { passed: true } }
onError Function which will be called if there is an error when submitting the form.
Returns JSON object.
e.g. { "success": false, "code": 1200, "http_code": 401, "message": "Unauthorized", "response": null, "metadata": [] }

Login

Click to expand
pxUserFrontend.showLoginForm({
    containerElement: 'pxUserLogin',
    fallbackTargetUrl: 'https://www.example.com/login',
    fallbackButtonText: 'Login!',
    showLoginWithEip: true,
    state: '7YiroLzzn2tmYdF58XlA6UVLjTbFJQRO',
    labels: {
        buttonText: 'Login!',
        username: 'Email-Address',
        password: 'Password',
        loginWithEntraId: 'Or login with your company\'s Microsoft login',
        emailOrUsername: 'Email/Username',
        continue: 'Continue',
        or: 'Or',
        back: 'Back',
        loginWithMicrosoft: 'Sign in with Microsoft',
        mfaInitTitle: 'MFA Setup',
        mfaInitMessage: 'Scan the QR code with your authenticator app or enter the secret manually.',
        mfaInitCodeLabel: 'Token:',
        mfaInitButtonText: 'Set up',
        mfaVerifyTitle: 'MFA Verify',
        mfaVerifyCodeLabel: 'Enter the code from your authenticator app.',
        mfaVerifyButtonText: 'Verify',
        mfaEnabledTitle: 'MFA Enabled',
        mfaEnabledMessage: 'Multi-factor authentication has been enabled.',
        mfaEnabledButtonText: 'Continue',
    },
    icons: {
        togglePassword: {
            password: true
        }
    },
    onSuccess: (data) => {
        doSomethingWith(data)
    },
    onError: (error) => {
        doSomethingWith(error)
    },
    onResetError: (data) => {
        // credentials accepted, but an additional step (e.g. MFA) is required
        // before login completes — host should reset any previous onError UI
        clearLoginErrorBanner()
    }
});
Parameter Description
token required
Security-Token from URL.
containerElement required
HTML-Element where this widget will be rendered in.
fallbackTargetUrl required
If there are errors in JS code, this is a fallback where form contents are sent to with a POST request.
fallbackButtonText required
If there are errors in JS code, this is the text for the submit button.
labels optional Labels for button and form elements.
Default: { buttonText: 'Login', username: 'Username', password: 'Password' }.
When MFA is triggered during login, the login widget forwards these labels to the internal MFA screens: mfaInitTitle, mfaInitMessage, mfaInitCodeLabel, mfaInitButtonText, mfaVerifyTitle, mfaVerifyCodeLabel, mfaVerifyButtonText, mfaEnabledTitle, mfaEnabledMessage, mfaEnabledButtonText.
icons.togglePassword optional Icons and onclick events for toggle (show/hide) the password.
Default: {password: true}. The default icon is eye.
E.g. use custom icon (bootstrap): {password: 'bi bi-eyeglasses'}
showLoginWithEip optional Show login with EIP form.
Default: false
eipLoginRedirectUri optional (with showLoginWithEip) EIP redirect URI (URL to which the user is redirected after successful login). If not set, we current url will be used. It must match one of the URLs configured in the EIP.
Default: null
state optional (with showLoginWithEip) A state which is sent back to the eipLoginRedirectUri to verify the login's source.
onSuccess Function which will be called if form is submitted successfully.
Returns JSON object.
e.g. { success: true, code: 200, http_code: 200, message: "OK", response: { access_token: 'abc', access_token_lifetime_minutes: 120, access_token_expiration_utc: '2021-10-07T13:15:39.120677Z', refresh_token: 'xyz', refresh_token_lifetime_minutes: 43200, refresh_token_expiration_utc: '2021-11-06T11:15:39.121160Z' } }
onError Function which will be called if there is an error when submitting the form.
Returns JSON object.
e.g. { "success": false, "code": 1200, "http_code": 401, "message": "Unauthorized", "response": null, "metadata": [] }
onResetError optional Use this callback to reset any error UI previously shown via onError. Fires when the server requires an additional step (e.g. MFA) after valid credentials but before onSuccess, so a stale error banner from a previous attempt does not stay visible during the challenge.
Returns JSON object.
e.g. { "success": true, "code": 200, "http_code": 200, "message": "OK", "response": { "challenge": "mfa/init", "challenge_token": "..." } }

Notes:

  • MFA init, verify, and enable screens are internal challenge screens. Product integrations should configure their labels on showLoginForm; they are not exposed as separate public widget methods.

Activate User With Activation Code

Click to expand
pxUserFrontend.showActivateUserByActivationCodeForm({
    containerElement: 'pxUserActivateUserByActivationCode',
    showPasswordRules: false,
    showUsernameRules: false,
    labels: {
        activationCode: 'Activation code',
        buttonTextActivationCode: 'Next',
        username: 'Username',
        passwordOne: 'Password',
        passwordTwo: 'Password again',
        buttonText: 'Activate',
    },
    icons: {
        togglePassword: {
            passwordOne: true,
            passwordTwo: true
        }
    },
    fallbackTargetUrl: 'https://www.example.com/activate-user-by-activation-code',
    fallbackButtonText: 'Activate User',
    onSuccessActivationCode: (data) => {
        doSomethingWith(data)
    },
    onErrorActivationCode: (error) => {
        doSomethingWith(error)
    },
    onSuccess: (data) => {
        doSomethingWith(data)
    },
    onError: (error) => {
        doSomethingWith(error)
    }
});
Parameter Description
containerElement required
HTML-Element where this widget will be rendered in.
showPasswordRules optional
Show password rules under the password field directly by typing.
Default: false
showUsernameRules optional
Show username rules under the username field directly by typing. If not defined, the value of showPasswordRules will be used.
Default: false
fallbackTargetUrl required
If there are errors in JS code, this is a fallback where form contents are sent to with a POST request.
fallbackButtonText required
If there are errors in JS code, this is the text for the submit button.
labels optional Labels for button and form elements.
Default: { buttonText: 'Activate user', activationCode: 'Activation code', username: 'Username', passwordOne: 'Password', passwordTwo: 'Password again' }
icons.togglePassword optional Icons and onclick events for toggle (show/hide) the password.
Default: {passwordOne: true, passwordTwo: true}. The default icon is eye.
E.g. use custom icon (bootstrap): {passwordOne: 'bi bi-eyeglasses', passwordTwo: true}
onSuccessActivationCode Function which will be called if form is submitted successfully.
Returns JSON object.
e.g. { success: true, code: 200, http_code: 200, message: "Success", response: { passed: true } }
onErrorActivationCode Function which will be called if there is an error when submitting the form.
Returns JSON object.
e.g. { "success": false, "code": 1200, "http_code": 401, "message": "Unauthorized", "response": null, "metadata": [] }
onSuccess Function which will be called if form is submitted successfully.
Returns JSON object.
e.g. { success: true, code: 200, http_code: 200, message: "Success", response: { passed: true } }
onError Function which will be called if there is an error when submitting the form.
Returns JSON object.
e.g. { "success": false, "code": 1200, "http_code": 401, "message": "Unauthorized", "response": null, "metadata": [] }

Activate User and Login

Click to expand
pxUserFrontend.showActivateUserLoginForm({
    token: 'abc123',
    containerElement: 'pxUserActivateUserLogin',
    showPasswordRules: false,
    fallbackTargetUrl: 'https://www.example.com/user-activate',
    fallbackButtonText: 'Activate user and login!',
    labels: {
        buttonText: 'Activate user and login!',
        passwordOne: 'Password',
        passwordTwo: 'Password again',
        mfaInitTitle: 'MFA Setup',
        mfaInitMessage: 'Scan the QR code with your authenticator app or enter the secret manually.',
        mfaInitCodeLabel: 'Token:',
        mfaInitButtonText: 'Set up',
        mfaVerifyTitle: 'MFA Verify',
        mfaVerifyCodeLabel: 'Enter the code from your authenticator app.',
        mfaVerifyButtonText: 'Verify',
        mfaEnabledTitle: 'MFA Enabled',
        mfaEnabledMessage: 'Multi-factor authentication has been enabled.',
        mfaEnabledButtonText: 'Continue',
    },
    icons: {
        togglePassword: {
            passwordOne: true,
            passwordTwo: true
        }
    },
    onSuccess: (data) => {
        doSomethingWith(data)
    },
    onError: (error) => {
        doSomethingWith(error)
    },
    onResetError: (data) => {
        // credentials accepted, additional step required (e.g. MFA) before login completes
        // host should reset any previous onError UI
        clearLoginErrorBanner()
    }
});
Parameter Description
token required
Security-Token from URL.
containerElement required
HTML-Element where this widget will be rendered in.
showPasswordRules optional
Show password rules under the password field directly by typing.
Default: false
fallbackTargetUrl required
If there are errors in JS code, this is a fallback where form contents are sent to with a POST request.
fallbackButtonText required
If there are errors in JS code, this is the text for the submit button.
labels optional Labels for button and form elements.
Default: { buttonText: 'Activate user', passwordOne: 'Password', passwordTwo: 'Password again' }.
When MFA is triggered after activation/login, this widget forwards these labels to the internal MFA screens: mfaInitTitle, mfaInitMessage, mfaInitCodeLabel, mfaInitButtonText, mfaVerifyTitle, mfaVerifyCodeLabel, mfaVerifyButtonText, mfaEnabledTitle, mfaEnabledMessage, mfaEnabledButtonText.
icons.togglePassword optional Icons and onclick events for toggle (show/hide) the password.
Default: {passwordOne: true, passwordTwo: true}. The default icon is eye.
E.g. use custom icon (bootstrap): {passwordOne: 'bi bi-eyeglasses', passwordTwo: true}
onSuccess Function which will be called if form is submitted successfully.
Returns JSON object.
e.g. { success: true, code: 200, http_code: 200, message: "OK", response: { access_token: 'abc', access_token_lifetime_minutes: 120, access_token_expiration_utc: '2021-10-07T13:15:39.120677Z', refresh_token: 'xyz', refresh_token_lifetime_minutes: 43200, refresh_token_expiration_utc: '2021-11-06T11:15:39.121160Z' } }
onError Function which will be called if there is an error when submitting the form.
Returns JSON object.
e.g. { "success": false, "code": 1200, "http_code": 401, "message": "Unauthorized", "response": null, "metadata": [] }
onResetError optional Use this callback to reset any error UI previously shown via onError. Fires when the server requires an additional step (e.g. MFA) after valid credentials but before onSuccess, so a stale error banner from a previous attempt does not stay visible during the challenge.
Returns JSON object.
e.g. { "success": true, "code": 200, "http_code": 200, "message": "OK", "response": { "challenge": "mfa/init", "challenge_token": "..." } }

Notes:

  • MFA init, verify, and enable screens are internal challenge screens. Product integrations should configure their labels on showActivateUserLoginForm; they are not exposed as separate public widget methods.

Activate User and Login with OIDC

Click to expand

OIDC-compatible variant of Activate User and Login. Instead of passing tokens to onSuccess, after a successful activation the user is logged in and the browser is redirected to the given redirect_uri with an OIDC authorization code (?code=...&state=...&codeType=auth_code&tenant=...&domain=...). The product exchanges that code at the OIDC token endpoint (PKCE required).

pxUserFrontend.showActivateUserLoginWithOidcForm({
    token: 'abc123',
    containerElement: 'pxUserActivateUserLoginWithOidc',
    client_id: 'your-client-id',
    redirect_uri: 'https://product.example/sso/callback',
    state: 'opaque-product-state',
    scope: 'openid',
    code_challenge: 'dEjftdeZ4C...hbUJUXk',
    code_challenge_method: 'S256',
    onError: (error) => { ... },
});
Parameter Description
token required
Security-Token from the activation URL.
containerElement required
ID of the element the widget iframe is rendered into.
client_id required
Registered OIDC client id of the product.
redirect_uri required
Registered redirect URI; receives code + state after success.
state strongly recommended
Opaque value returned unchanged on the redirect. Always send a unique, unguessable value and verify it on the callback to protect against CSRF.
scope required
Must contain openid.
code_challenge required
PKCE code challenge (S256 of your code_verifier).
code_challenge_method required
Only S256 is supported.

Notes:

  • onSuccess is not used to deliver tokens — after successful activation the user is logged in and the top-level page is redirected to redirect_uri.
  • MFA challenges are handled inside the widget, exactly like the classic variant.
  • All other parameters (labels, icons, showPasswordRules, fallbackTargetUrl, ...) work as in Activate User and Login.

Password set by forgot password code

Click to expand
pxUserFrontend.showPasswordSetByForgotPasswordCodeForm({
    containerElement: 'pxUserPasswordSetByForgotPasswordCode',
    showPasswordRules: false,
    labels: {
        username: 'Username',
        forgotPasswordCode: 'Forgot password code',
        passwordOne: 'Password',
        passwordTwo: 'Password again',
        buttonText: 'Set password',
    },
    icons: {
        togglePassword: {
            passwordOne: true,
            passwordTwo: true
        }
    },
    fallbackTargetUrl: 'https://www.example.com/password-set-by-forgot-password-code',
    fallbackButtonText: 'Set password',
    onSuccess: (data) => {
        doSomethingWith(data)
    },
    onError: (error) => {
        doSomethingWith(error)
    }
});
Parameter Description
containerElement required
HTML-Element where this widget will be rendered in.
showPasswordRules optional
Show password rules under the password field directly by typing.
Default: false
fallbackTargetUrl required
If there are errors in JS code, this is a fallback where form contents are sent to with a POST request.
fallbackButtonText required
If there are errors in JS code, this is the text for the submit button.
labels optional Labels for button and form elements.
Default: { buttonText: 'Password set', username: 'Username', forgotPasswordCode: 'Forgot password code', passwordOne: 'Password', passwordTwo: 'Password again' }
icons.togglePassword optional Icons and onclick events for toggle (show/hide) the password.
Default: {passwordOne: true, passwordTwo: true}. The default icon is eye.
E.g. use custom icon (bootstrap): {passwordOne: 'bi bi-eyeglasses', passwordTwo: true}
onSuccess Function which will be called if form is submitted successfully.
Returns JSON object.
e.g. { success: true, code: 200, http_code: 200, message: "Success", response: { passed: true } }
onError Function which will be called if there is an error when submitting the form.
Returns JSON object.
e.g. { "success": false, "code": 1200, "http_code": 401, "message": "Unauthorized", "response": null, "metadata": [] }

Password set by forgot password code and login

Click to expand
pxUserFrontend.showPasswordSetByForgotPasswordCodeLoginForm({
    containerElement: 'pxUserPasswordSetByForgotPasswordCodeLogin',
    showPasswordRules: false,
    labels: {
        username: 'Username',
        forgotPasswordCode: 'Forgot password code',
        passwordOne: 'Password',
        passwordTwo: 'Password again',
        buttonText: 'Set password and login',
        mfaInitTitle: 'MFA Setup',
        mfaInitMessage: 'Scan the QR code with your authenticator app or enter the secret manually.',
        mfaInitCodeLabel: 'Token:',
        mfaInitButtonText: 'Set up',
        mfaVerifyTitle: 'MFA Verify',
        mfaVerifyCodeLabel: 'Enter the code from your authenticator app.',
        mfaVerifyButtonText: 'Verify',
        mfaEnabledTitle: 'MFA Enabled',
        mfaEnabledMessage: 'Multi-factor authentication has been enabled.',
        mfaEnabledButtonText: 'Continue',
    },
    icons: {
        togglePassword: {
            passwordOne: true,
            passwordTwo: true
        }
    },
    fallbackTargetUrl: 'https://www.example.com/password-set-by-forgot-password-code-login',
    fallbackButtonText: 'Set password and login',
    onSuccess: (data) => {
        doSomethingWith(data)
    },
    onError: (error) => {
        doSomethingWith(error)
    },
    onResetError: (data) => {
        // credentials accepted, additional step required (e.g. MFA) before login completes
        // host should reset any previous onError UI
        clearLoginErrorBanner()
    }
});
Parameter Description
containerElement required
HTML-Element where this widget will be rendered in.
showPasswordRules optional
Show password rules under the password field directly by typing.
Default: false
fallbackTargetUrl required
If there are errors in JS code, this is a fallback where form contents are sent to with a POST request.
fallbackButtonText required
If there are errors in JS code, this is the text for the submit button.
labels optional Labels for button and form elements.
Default: { buttonText: 'Password set', username: 'Username', forgotPasswordCode: 'Forgot password code', passwordOne: 'Password', passwordTwo: 'Password again' }.
When MFA is triggered after setting the password and logging in, this widget forwards these labels to the internal MFA screens: mfaInitTitle, mfaInitMessage, mfaInitCodeLabel, mfaInitButtonText, mfaVerifyTitle, mfaVerifyCodeLabel, mfaVerifyButtonText, mfaEnabledTitle, mfaEnabledMessage, mfaEnabledButtonText.
icons.togglePassword optional Icons and onclick events for toggle (show/hide) the password.
Default: {passwordOne: true, passwordTwo: true}. The default icon is eye.
E.g. use custom icon (bootstrap): {passwordOne: 'bi bi-eyeglasses', passwordTwo: true}
onSuccess Function which will be called if form is submitted successfully.
Returns JSON object.
e.g. { success: true, code: 200, http_code: 200, message: "OK", response: { access_token: 'abc', access_token_lifetime_minutes: 120, access_token_expiration_utc: '2021-10-07T13:15:39.120677Z', refresh_token: 'xyz', refresh_token_lifetime_minutes: 43200, refresh_token_expiration_utc: '2021-11-06T11:15:39.121160Z' } }
onError Function which will be called if there is an error when submitting the form.
Returns JSON object.
e.g. { "success": false, "code": 1200, "http_code": 401, "message": "Unauthorized", "response": null, "metadata": [] }
onResetError optional Use this callback to reset any error UI previously shown via onError. Fires when the server requires an additional step (e.g. MFA) after valid credentials but before onSuccess, so a stale error banner from a previous attempt does not stay visible during the challenge.
Returns JSON object.
e.g. { "success": true, "code": 200, "http_code": 200, "message": "OK", "response": { "challenge": "mfa/init", "challenge_token": "..." } }

Notes:

  • MFA init, verify, and enable screens are internal challenge screens. Product integrations should configure their labels on showPasswordSetByForgotPasswordCodeLoginForm; they are not exposed as separate public widget methods.

Password Set by Forgot-Password-Code and Login with OIDC

Click to expand

OIDC-compatible variant of Password set by forgot password code and login. Instead of passing tokens to onSuccess, after successfully setting the password the user is logged in and the browser is redirected to the given redirect_uri with an OIDC authorization code (?code=...&state=...&codeType=auth_code&tenant=...&domain=...). The product exchanges that code at the OIDC token endpoint (PKCE required).

pxUserFrontend.showPasswordSetByForgotPasswordCodeLoginWithOidcForm({
    forgotPasswordCode: 'abc123',
    username: 'jane.doe@example.com',
    containerElement: 'pxUserPasswordSetByForgotPasswordCodeLoginWithOidc',
    client_id: 'your-client-id',
    redirect_uri: 'https://product.example/sso/callback',
    state: 'opaque-product-state',
    scope: 'openid',
    code_challenge: 'dEjftdeZ4C...hbUJUXk',
    code_challenge_method: 'S256',
    onError: (error) => { ... },
});
Parameter Description
forgotPasswordCode required
Forgot-password code from the reset link/email.
username required
Username the forgot-password code was issued for.
containerElement required
ID of the element the widget iframe is rendered into.
client_id required
Registered OIDC client id of the product.
redirect_uri required
Registered redirect URI; receives code + state after success.
state strongly recommended
Opaque value returned unchanged on the redirect. Always send a unique, unguessable value and verify it on the callback to protect against CSRF.
scope required
Must contain openid.
code_challenge required
PKCE code challenge (S256 of your code_verifier).
code_challenge_method required
Only S256 is supported.

Notes:

  • onSuccess is not used to deliver tokens — after successfully setting the password the user is logged in and the top-level page is redirected to redirect_uri.
  • MFA challenges are handled inside the widget, exactly like the classic variant.
  • All other parameters (labels, icons, showPasswordRules, fallbackTargetUrl, ...) work as in Password set by forgot password code and login.

Confirm New Email

Click to expand
    pxUserFrontend.showConfirmNewEmailForm({
        token: 'abc123',
        containerElement: 'pxUserConfirmNewEmail',
        fallbackTargetUrl: 'https://www.example.com/confirm-new-email',
        fallbackButtonText: 'Confirm New Email',
        onSuccess: (data) => {
            doSomethingWith(data)
        },
        onError: (error) => {
            doSomethingWith(error)
        }
    });
Parameter Description
containerElement required
HTML-Element where this widget will be rendered in.
fallbackTargetUrl required
If there are errors in JS code, this is a fallback where form contents are sent to with a POST request.
fallbackButtonText required
If there are errors in JS code, this is the text for the submit button.
onSuccess Function which will be called if form is submitted successfully.
Returns JSON object.
e.g. { success: true, code: 200, http_code: 200, message: "Success", response: { passed: true } }
onError Function which will be called if there is an error when submitting the form.
Returns JSON object.
e.g. { "success": false, "code": 1200, "http_code": 401, "message": "Unauthorized", "response": null, "metadata": [] }

Alternative Email

Click to expand

Shown to a customer whose Fulfillment subscription collided with an existing account under the same email address. The customer receives a mail with a token link; the widget checks the state of the correction and renders the form (one field: the alternative address) or a closing sentence when the link is invalid, expired, or already used. Submissions are throttled per token and per client IP.

    pxUserFrontend.showAlternativeEmailForm({
        token: 'ale_abc123',
        containerElement: 'pxUserAlternativeEmail',
        fallbackTargetUrl: 'https://www.example.com/alternative-email',
        fallbackButtonText: 'Send',
        onSuccess: (data) => {
            doSomethingWith(data)
        },
        onError: (error) => {
            doSomethingWith(error)
        }
    });
Parameter Description
token required
Token from the customer's mail link.
containerElement required
HTML-Element where this widget will be rendered in.
fallbackTargetUrl required
If there are errors in JS code, this is a fallback where form contents are sent to with a POST request.
fallbackButtonText required
If there are errors in JS code, this is the text for the submit button.
labels optional Overrides for the texts inside the iframe: title, email, buttonText.
onSuccess Function which will be called if form is submitted successfully.
Returns JSON object.
e.g. { success: true, code: 200, http_code: 200, message: "Success", response: null }
onError Function which will be called on client-side validation ({ validation_code: 422, message }), on 400 (the address was rejected by the server-side check), on 422 code 1250 (address already in use), on 429 code 1005 (throttled), on the token errors 1270 / 1271 / 1272 and on any other failure of the submission.
Payloads the iframe has already rendered itself carry displayed_in_frame: true, so the host can leave its own error pane untouched.

Alternative Email (standalone)

Click to expand

A hosted page that embeds the Alternative Email widget, for customers whose domain does not offer a page of its own. Which of the two the customer's mail links to is decided by the domain setting mail.placeholders.alternative_email_url: empty means this page, and a URL means the product's own page. Either way the link carries the token.

Tenant and domain are one path segment, tenant:domain. Missing or invalid parameters render the standalone error page with HTTP 400 instead of the widget.


    GET https://user-frontend.api.preprod.pl-x.cloud/vnr:px_teach/alternative-email
        ?token=ale_abc123
        &locale=de
        &css_url=https://example.com/widget-custom.css
        &logo_url=https://example.com/brand/logo.svg
        &favicon_url=https://example.com/brand/favicon.png
        &form_title=Acme%20Konto
        &show_spinner=true
Parameter Description
token required The token from the customer's mail link.
locale optional de or en; may also be sent as a locale request header, which wins over the query parameter. Any other value falls back to de.
css_url optional Stylesheet for both the page and the widget inside it. Defaults to the built-in sso.css.
logo_url optional Custom logo above the form. Defaults to the built-in logo.
favicon_url optional Custom favicon. Defaults to the built-in icon.
form_title optional Custom text for the browser tab and the heading above the form. Defaults to the translated title.
show_spinner optional true or false. Shows a loading spinner while the widget loads and inside the submit button while the address is sent. Default: true.

The link in the customer's mail carries only the token, so in practice these theming parameters apply only to a domain that overrides mail.placeholders.alternative_email_url with this page's own address.


Configure an External Identity Provider

Click to expand

The widget auto-detects whether the owner already has an EIP configured and adjusts itself — no change to how you call showEipConfigForm is needed:

  • Not configured yet: a blank form (Tenant ID, Client ID, Client Secret, Group ID, optional Secret valid until).
  • Already configured: Tenant ID, Client ID and Group ID are prefilled and read-only. The stored secret is never sent to the browser, so Client Secret must always be re-entered to submit — even if you only want to change the validity date. Secret valid until is prefilled with the stored value and stays editable.

Both cases render the same Test/Save buttons and post to the same endpoint — Test validates the entered secret against Entra without persisting anything; Save persists it (creating the EIP config on first save, overwriting it afterwards).

pxUserFrontend.showEipConfigForm({
    token: 'abc123',
    containerElement: 'pxUserEipConfig',
    fallbackTargetUrl: 'https://www.example.com/eip-config',
    fallbackButtonText: 'Save config',
    labels: {
        tenantId: 'Tenant ID',
        clientId: 'Client ID',
        clientSecret: 'Client Secret',
        groupId: 'Group ID',
        secretValidUntil: 'Secret valid until',
        testButtonText: 'Test',
        saveButtonText: 'Save',
    },
    onSuccess: (payload) => {
        const source = payload.source;
        const data = payload.data;

        if (source === 'test') {
            showAlertSuccess('Config is valid. Found ' + data.response.userCount + ' users.');
        } else {
            showAlertSuccess('Config saved');
        }
    },
    onError: (error) => {
        showAlertDanger(`Error: ${error.data.message}, Source: ${error.source}`);
    }
});
Parameter Description
token required
Security-Token from URL.
containerElement required
HTML-Element where this widget will be rendered in.
fallbackTargetUrl required
If there are errors in JS code, this is a fallback where form contents are sent to with a POST request.
fallbackButtonText required
If there are errors in JS code, this is the text for the submit button.
labels optional Labels for button and form elements.
Default values are used in the example above.
onSuccess Function which will be called if form is submitted successfully.
You can access an object in the callback argument. There are two types of responses you can get (one from the test endpoint and one from the save endpoint).
E.g. (Test response):
{ source: "test", data: { success: true, code: 200, http_code: 200, message: "Tested successfully.", response: { userCount: 450 } } }
E.g. (Save response):
{ source: "save", data: { success: true, code: 200, http_code: 200, message: "Credentials stored.", response: null } }
onError Function which will be called if there is an error when submitting the form.
You can access an object in the callback argument.
E.g. (Test response):
{ source: "test", data: { success: false, code: 422, http_code: 422, message: "Test not successful", response: null }
E.g. (Save response):
{ source: "save", data: { success: false, code: 500, http_code: 500, message: "Credentials storing failed.", response: null } }

Secret valid until — optional field, shown in both modes.

  • Format: German DD.MM.YYYY (e.g. 25.11.2026).
  • Leave empty to clear/skip it; a filled-in date must not be in the past and at most 2 years from today.
  • It is not verified against Entra's actual secret expiry — it's stored as declared.
  • The submitted value is authoritative: a date sets it, blank clears a previously stored one.
  • An invalid value fails client-side validation the same way an empty required field does ({ validation_code: 422, message } via onError), before any request is sent.

Single Sign-On (widget)

Click to expand

Single Sign-On Widget follows OAuth 2.0 Authorization Code Grant. See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1 for more information.

pxUserFrontend.showLoginSsoForm({
    // OAuth 2.0 + PKCE
    client_id: 'abc123',
    state: '7YiroLzzn2tmYdF58XlA6UVLjTbFJQRO',
    redirect_uri: 'https://user-frontend.api.pl-x.cloud/preview/dashboard',
    code_challenge: 'ZjBhZmE1YjQxMzEzYjY4NjQzMjM0YzcyM2I3M2JiMDY2MzQ0NTlmOGY1YjM2ZmZmOTIyNzJhY2I1YTliYjY2ZA',
    code_challenge_method: 'S256',
    // widget configuration
    containerElement: 'pxUserLoginSso',
    fallbackTargetUrl: 'https://www.example.com/login',
    fallbackButtonText: 'Login!',
    showLoginWithEip: true,
    eipLoginRedirectUri: 'https://www.example.com/login',
    selected_account: 'ten:domain:user-id',
    messages: {
        ssoLoginFailed: 'Custom error message must be defined here.'
    },
    labels: {
        buttonText: 'Login!',
        username: 'Email-Address',
        password: 'Password',
        loginWithEntraId: 'Or login with your company\'s Microsoft login',
        emailOrUsername: 'Email/Username',
        continue: 'Continue',
    },
    icons: {
        togglePassword: {
            password: true
        }
    },
    onSuccess: (data) => {
        doSomethingWith(data)
    },
    onError: (error) => {
        doSomethingWith(error)
    },
    onResetError: (data) => {
        // credentials accepted, additional step required (e.g. MFA) before redirect
        // host should reset any previous onError UI
        clearLoginErrorBanner()
    }
});
Parameter Description
client_id required
The client identifier. [1]
redirect_uri required Where to redirect after successful login. [2]
state recommended A state which is sent back to the redirect_url to verify the login's source [3]
code_challenge required A code challenge for the PKCE flow. Hints: use raw output of hash method and make the base64-encoded-string url-safe [4]
code_challenge_method required The method used to generate the code challenge. Currently only "S256" is supported [5]
containerElement required
HTML-Element where this widget will be rendered in.
fallbackTargetUrl required
If there are errors in JS code, this is a fallback where form contents are sent to with a POST request.
messages optional Messages for the widget.
Default: { ssoLoginFailed: 'Login is not possible. Please check your username and password and try again. Your account may not be configured for SSO login. Please contact your administrator.' }
fallbackButtonText required
If there are errors in JS code, this is the text for the submit button.
labels optional Labels for button and form elements.
Default: { buttonText: 'Login', username: 'Username', password: 'Password' }
icons.togglePassword optional Icons and onclick events for toggle (show/hide) the password.
Default: {password: true}. The default icon is eye.
E.g. use custom icon (bootstrap): {password: 'bi bi-eyeglasses'}
showLoginWithEip optional Show login with EIP form.
Default: false
eipLoginRedirectUri optional EIP redirect URI (URL to which the user is redirected after successful login). If not set, we current url will be used. It must match one of the URLs configured in the EIP.
Default: null
onSuccess Not used for SSO. Instead, the user will be redirected back to defined redirect_uri. The url contains following query parameters: code and state (see: https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2). You have to use them to request access token (see: https://user.api.pl-x.cloud/docs/#token-POSTv1-oauth-token--token_type-- with grant_type=authentication_code)
onError Will be documented soon
onResetError optional Use this callback to reset any error UI previously shown via onError. Fires when the server requires an additional step (e.g. MFA) after valid credentials but before the final redirect, so a stale error banner from a previous attempt does not stay visible during the challenge.
Returns JSON object.
e.g. { "success": true, "code": 200, "http_code": 200, "message": "OK", "response": { "challenge": "mfa/init", "challenge_token": "..." } }
References

[1]: See https://datatracker.ietf.org/doc/html/rfc6749#section-2.2 for more information about the client_id parameter.

[2]: See https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.2 for more information about the redirect_uri parameter.

[3]: See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.1 for more information about the state parameter.

[4]: See https://datatracker.ietf.org/doc/html/rfc7636#section-4.2 and https://datatracker.ietf.org/doc/html/rfc7636#appendix-A for more information about the code_challenge parameter.

[5]: See https://datatracker.ietf.org/doc/html/rfc7636#section-4.3 for more information about the code_challenge_method parameter.


Open ID Connect (widget)

Click to expand

Open ID Connect Widget follows OIDC 1.0 Authorization Code Grant. See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1 for more information.

pxUserFrontend.showLoginOidcForm({
    client_id: 'abc123',
    state: '7YiroLzzn2tmYdF58XlA6UVLjTbFJQRO',
    redirect_uri: 'https://user-frontend.api.pl-x.cloud/preview/dashboard'
    code_challenge: 'ZjBhZmE1YjQxMzEzYjY4NjQzMjM0YzcyM2I3M2JiMDY2MzQ0NTlmOGY1YjM2ZmZmOTIyNzJhY2I1YTliYjY2ZA',
    code_challenge_method: 'S256',
    // widget configuration
    containerElement: 'pxUserLoginOidc',
    fallbackTargetUrl: 'https://www.example.com/login',
    fallbackButtonText: 'Login!',
    showLoginWithEip: true,
    eipLoginRedirectUri: 'https://www.example.com/login',
    scope: 'openid profile email',
    prompt: 'login',
    labels: {
        buttonText: 'Login!',
        username: 'Email-Address',
        password: 'Password',
        loginWithEntraId: 'Or login with your company\'s Microsoft login',
        emailOrUsername: 'Email/Username',
        continue: 'Continue',
    },
    icons: {
        togglePassword: {
            password: true
        }
    },
    onSuccess: (data) => {
        doSomethingWith(data)
    },
    onError: (error) => {
        doSomethingWith(error)
    },
    onResetError: (data) => {
        // credentials accepted, additional step required (e.g. MFA) before redirect
        // host should reset any previous onError UI
        clearLoginErrorBanner()
    }
});
Parameter Description
client_id required
The client identifier. [1]
redirect_uri required Where to redirect after successful login. [2]
state recommended A state which is sent back to the redirect_url to verify the login's source [3]
code_challenge required A code challenge for the PKCE flow. Hints: use raw output of hash method and make the base64-encoded-string url-safe [4]
code_challenge_method required The method used to generate the code challenge. Currently only "S256" is supported [5]
containerElement required
HTML-Element where this widget will be rendered in.
fallbackTargetUrl required
If there are errors in JS code, this is a fallback where form contents are sent to with a POST request.
fallbackButtonText required
If there are errors in JS code, this is the text for the submit button.
labels optional Labels for button and form elements.
Default: { buttonText: 'Login', username: 'Username', password: 'Password' }
icons.togglePassword optional Icons and onclick events for toggle (show/hide) the password.
Default: {password: true}. The default icon is eye.
E.g. use custom icon (bootstrap): {password: 'bi bi-eyeglasses'}
showLoginWithEip optional Show login with EIP form.
Default: false
scope required for OIDC The scope of data to be retrieved
prompt optional for OIDC The type of prompt to control user interaction:
- login: Force the user to re-authenticate.
- none: Silent authentication without user interaction.
- select_account: Prompt the End-User to select a user account.
Any other value (e.g. the literal string "undefined") is ignored and treated as if prompt had not been sent.
eipLoginRedirectUri optional EIP redirect URI (URL to which the user is redirected after successful login). If not set, we current url will be used. It must match one of the URLs configured in the EIP.
Default: null
onSuccess Not used for SSO. Instead, the user will be redirected back to defined redirect_uri. The url contains following query parameters: code and state (see: https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2). You have to use them to request access token (see: https://user.api.pl-x.cloud/docs/#token-POSTv1-oauth-token--token_type-- with grant_type=authentication_code)
onError Will be documented soon
onResetError optional Use this callback to reset any error UI previously shown via onError. Fires when the server requires an additional step (e.g. MFA) after valid credentials but before the final redirect, so a stale error banner from a previous attempt does not stay visible during the challenge.
Returns JSON object.
e.g. { "success": true, "code": 200, "http_code": 200, "message": "OK", "response": { "challenge": "mfa/init", "challenge_token": "..." } }
References

[1]: See https://datatracker.ietf.org/doc/html/rfc6749#section-2.2 for more information about the client_id parameter.

[2]: See https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.2 for more information about the redirect_uri parameter.

[3]: See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.1 for more information about the state parameter.

[4]: See https://datatracker.ietf.org/doc/html/rfc7636#section-4.2 and https://datatracker.ietf.org/doc/html/rfc7636#appendix-A for more information about the code_challenge parameter.

[5]: See https://datatracker.ietf.org/doc/html/rfc7636#section-4.3 for more information about the code_challenge_method parameter.


Single Sign-On (standalone)

Click to expand

Single Sign-On Standalone follows OAuth 2.0 Authorization Code Grant. See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1 for more information.

When embedding the widget via PxModUser, set mode: 'standalone' to ensure production uses https://sso-login.pl-x.com.


    OAuth GET https://user-frontend.api.preprod.pl-x.cloud/plx:pxc/oauth2/v2.0/authorize
        ?response_type=code
        &client_id=demo_user_frontend_preview
        &redirect_uri=https%3A%2F%2Fexample.com%2Fdashboard
        &state=vHH_GWJv.-REfY~X
        &code_challenge=ZjBhZmE1YjQxMzEzYjY4NjQzMjM0YzcyM2I3M2JiMDY2MzQ0NTlmOGY1YjM2ZmZmOTIyNzJhY2I1YTliYjY2ZA
        &code_challenge_method=S256
        &css_url=https://example.com/widget-custom.css
        &logo_url=https://example.com/brand/logo.svg
        &favicon_url=https://example.com/brand/favicon.png
        &form_title=Acme%20Login
        &show_spinner=true
        &messages={"ssoLoginFailed":"Custom message here"}
        &labels={"emailOrUsername":"Email-Adresse","buttonText":"Anmelden"}
    OIDC GET https://user-frontend.api.preprod.pl-x.cloud/plx:pxc/oidc/v1.0/authorize
        ?response_type=code
        &client_id=demo_user_frontend_preview
        &redirect_uri=https%3A%2F%2Fexample.com%2Fdashboard
        &state=vHH_GWJv.-REfY~X
        &code_challenge=ZjBhZmE1YjQxMzEzYjY4NjQzMjM0YzcyM2I3M2JiMDY2MzQ0NTlmOGY1YjM2ZmZmOTIyNzJhY2I1YTliYjY2ZA
        &code_challenge_method=S256
        &css_url=https://example.com/widget-custom.css
        &logo_url=https://example.com/brand/logo.svg
        &favicon_url=https://example.com/brand/favicon.png
        &form_title=Acme%20Login%20OIDC
        &prompt=none
        &scope=openid%20profile%20email

    EXAMPLE redirect to: https://example.com/dashboard?code=eyJpdiI6IjBT..yI6IiJ9&state=vHH_GWJv.-REfY~X&mode=
Parameter Description
response_type required
Currently only 'code' is supported. [1]
client_id required
The client identifier. [2]
redirect_uri required Where to redirect after successful login. [3]
state recommended A state which is sent back to the redirect_url to verify the login's source [4]
code_challenge required A code challenge for the PKCE flow. Hints: use raw output of hash method and make the base64-encoded-string url-safe [5]
code_challenge_method required The method used to generate the code challenge. Currently only "S256" is supported [6]
tenant required The tenant identifier.
domain required The domain identifier.
scope required for OIDC The scope of data to be retrieved
prompt optional for OIDC The type of prompt (login, none, select_account). Any other value is ignored and treated as if prompt had not been sent.
css_url optional The URL to the CSS file used for customization of login form.
logo_url optional The URL to a custom logo image for the standalone login page. Defaults to the built-in logo when omitted.
favicon_url optional The URL to a custom favicon for the standalone login page. Defaults to the built-in icon when omitted.
form_title optional Custom title text shown above the standalone login form. Defaults to the built-in title when omitted.
show_spinner optional When true, displays a loading spinner inside the submit button during login. Default: false.
messages optional Messages for the widget.
Example: { ssoLoginFailed: 'Login is not possible. Please check your username and password and try again. Your account may not be configured for SSO login. Please contact your administrator.' }
labels optional JSON object overriding individual UI labels in the standalone login form. Same keys as the labels parameter of the integrated showLoginForm (e.g. buttonText, username, password, emailOrUsername, back, continue, or, loginWithEntraId).
Example: { emailOrUsername: 'Email-Adresse' }
Responses

The endpoint can return two types of responses:

  1. Success Response

    • Renders the login widget when all parameters are valid
    • Shows the platform X login form with:
      • Email/Username field
      • Password field
      • Login button
      • Optional EIP login section
  2. Error Response

    • Renders an error page when validation fails
    • Shows detailed information about what went wrong
    • HTTP Status Code: 400 Bad Request

Common validation errors:

  • Missing required parameters
  • Invalid response_type (must be 'code')
  • Invalid code_challenge_method (must be 'S256')
  • Invalid redirect_uri format
  • Mismatched client_id and redirect_uri
  • Invalid tenant or domain

Important note: the authorization code appended to the redirect_uri is short-lived and single-use. Exchange it for tokens immediately after the redirect.

After successful login, the user will be redirected to the specified redirect_uri with the authorization code and state parameters.

References

[1]: See https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.1 for more information about the response_type parameter.

[2]: See https://datatracker.ietf.org/doc/html/rfc6749#section-2.2 for more information about the client_id parameter.

[3]: See https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.2 for more information about the redirect_uri parameter.

[4]: See https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.1 for more information about the state parameter.

[5]: See https://datatracker.ietf.org/doc/html/rfc7636#section-4.2 and https://datatracker.ietf.org/doc/html/rfc7636#appendix-A for more information about the code_challenge parameter.

[6]: See https://datatracker.ietf.org/doc/html/rfc7636#section-4.3 for more information about the code_challenge_method parameter.


MFA Setup

Click to expand

The MFA Setup widget allows a logged-in user to enable or disable multi-factor authentication. If MFA is not enabled, it renders a button to start the setup. On successful setup initiation, the widget automatically proceeds to the MFA initialization flow (QR code/verification step).

pxUserFrontend.showMfaSetupForm({
    token: 'abc123',
    containerElement: 'pxUserMfaSetup',
    labels: {
        mfaSetupTitle: 'MFA Setup',
        mfaSetupSetupButtonText: 'Setup MFA',
        mfaSetupAlreadyEnabled: 'MFA already enabled',
        mfaSetupDisableButtonText: 'Disable MFA',
        mfaSetupUserNotFound: 'User data not found.',
        mfaInitTitle: 'MFA Setup',
        mfaInitMessage: 'Scan the QR code with your authenticator app or enter the secret manually.',
        mfaInitCodeLabel: 'Token:',
        mfaInitButtonText: 'Set up',
        mfaSetupCompleteTitle: 'MFA Setup Complete',
        mfaSetupCompleteHeading: 'MFA is ready',
        mfaSetupCompleteMessage: 'Multi-factor authentication has been enabled.'
    },
    onSuccess: (payload) => {
        // Called on successful actions (e.g., disable completed or flow progressed)
        doSomethingWith(payload)
    },
    onError: (error) => {
        doSomethingWith(error)
    }
});
Parameter Description
token required
Security-Token from URL.
containerElement required
HTML-Element where this widget will be rendered in.
labels optional Labels for MFA setup, MFA initialization, and setup completion screens.
Supported keys: mfaSetupTitle, mfaSetupSetupButtonText, mfaSetupAlreadyEnabled, mfaSetupDisableButtonText, mfaSetupUserNotFound, mfaInitTitle, mfaInitMessage, mfaInitCodeLabel, mfaInitButtonText, mfaSetupCompleteTitle, mfaSetupCompleteHeading, mfaSetupCompleteMessage.
onSuccess Function called on successful actions. Receives payload object.
onError Function called on errors. Receives payload object.

Notes:

  • If the user has MFA disabled, the widget starts the setup and then automatically navigates to the MFA initialization widget.
  • If the user already has MFA enabled, the widget renders a button to disable MFA.
  • MFA initialization and setup completion are internal screens of this setup flow. Product integrations should configure their labels on showMfaSetupForm; they are not exposed as separate public widget methods.

Change Password

Click to expand

Lets a logged-in user change their own password: current password, new password, new password again. The new password has to follow the same policy as in the other password widgets, and the policy can be shown in the widget with showPasswordRules. A successful change revokes all refresh tokens of the user, the one of the current session included, so the host has to expect a new sign-in once the current access token expires. No email is sent.

The access token never reaches the browser. The host passes the preferred username of its logged-in user to the widget. The user is identified by username and current password, and the change is only accepted while the user has an active session.

    pxUserFrontend.showChangePasswordForm({
        preferred_username: 'preferredUsernameOfTheLoggedInUser',
        showPasswordRules: true,
        containerElement: 'pxUserChangePassword',
        fallbackTargetUrl: 'https://www.example.com/my-account',
        fallbackButtonText: 'Change password',
        onSuccess: (data) => {
            doSomethingWith(data)
        },
        onError: (error) => {
            doSomethingWith(error)
        }
    });
Parameter Description
preferred_username required
Preferred username of the logged-in user. Never pass the access token.
containerElement required
HTML-Element where this widget will be rendered in.
fallbackTargetUrl required
Required by the widget framework like for every widget.
fallbackButtonText required
Required by the widget framework like for every widget.
showPasswordRules optional
true shows the password policy in the widget. Default: false.
labels optional Overrides for the texts inside the iframe: title, currentPassword, passwordOne, passwordTwo, buttonText, successText.
icons optional
Icons to toggle the visibility of a password field: icons: { togglePassword: { current_password: '<svg ...>', passwordOne: '<svg ...>', passwordTwo: '<svg ...>' } }.
onSuccess Function which will be called if the password was changed.
Returns JSON object.
e.g. { success: true, code: 200, http_code: 200, message: "Success", response: null }
onError Function which will be called on client-side validation ({ validation_code: 422, message }), on the live check of the new password while the user types ({ validation_code: 200 } when the input is fine, 1001 / 1002 when it is not) and on every refusal: wrong current password (400, code 1004), new password rejected (400, code 1218), too many attempts (429, code 1005) and any other failure.
Payloads the iframe has already rendered itself carry displayed_in_frame: true, so the host can leave its own error pane untouched.

Notes:

  • Users that sign in through an external identity provider (Entra/BFD) cannot change their password here. The change is refused for them (400, code 1006); the host should show its own explanation instead of the widget.
  • The password policy cannot be configured per widget; it is the one of the domain.
  • The error (#errorMessage) and success (.successMessage) texts inside the iframe come with a default red and green box. Restyle them in your cssUrl stylesheet, either with your own rules or by setting --plx-message-error-color|bg|border and --plx-message-success-color|bg|border on :root.
  • Wrong current passwords count on the same attempt limit as the login, so a locked-out user cannot log in either until the limit has passed.

Account Linking

Click to expand
pxUserFrontend.showALS({
    hostUrlsParams: new URLSearchParams(window.location.search),
    redirect_uri: 'https://www.example.com/endpoint',  // <-- The product URL with login widget
    base_uri: 'https://www.example.com/endpoint', // <-- The product URL were the ALS widget is integrated
    ...({}),
    containerElement: 'pxUserAls',
    onSuccess: () => {},
    onError: () => {}
});

The ALS Widget knows which products to connect with each other. When using the ALS widget and start linking user accounts, you will first redirected to the login of the first product. After the user successfully logs into the first product he or she is redirected to the base_uri which must lead back to the page with the ALS Widget, which then recognize the first auth. Then it will redirect to the second product where the user has to sign in also. After the second successful login the user is once again redirected back to the base_uri where the ALS Widget will show him or her a confirmation that the accounts have been connected. There a Button will display which links to the provided redirect_uri. This Button and thus the redirect_uri should Link to a page where the OIDC Login Widget will display. The Login Widget will notice that the user has logged in during the ALS process and log the user into the portal.

Parameter Description
stage required
The stage your site runs on. Defines whether widgets should be served from testing or production environment.
Available values: preprod / prod.
domain required
Domain code which is provided by VNR for every product (e.g. px-user-frontend-preview).
tenant required
Tenant code which is provided by VNR for every product (e.g. demo).
cssUrl Absolute path to a CSS file to add custom styling to all widgets.
language Default language for messages and labels.
Available values: en / de.
labels optional Labels for button and form elements.
Default values are used in the example above.
onSuccess Function which will be called if form is submitted successfully.
onError Function which will be called if there is an error when submitting the form

Security notes

Several widgets take a token that your page reads from its own URL (password set, activation, e-mail confirmation, alternative email, MFA setup). Read it once and pass it to the widget. Once the widget's show… promise has resolved, remove only the token parameter from the address bar so it does not stay in browser history or leak through the Referer header, and leave every other parameter in place (the SSO and OIDC widgets rely on them):

await pxUserFrontend.showPasswordSetForm({ token, /* ... */ });
const url = new URL(location.href);
url.searchParams.delete('token');
history.replaceState({}, '', url);

Do not log full request URLs on your side.

Errors reference

Use this section to map error codes and messages to translations in your product. Errors can originate from user-frontend (configuration, client-side validation, SSO/OIDC flows) or be passed through from the user API (responses from login, activation, password, MFA, EIP, and related widget endpoints).

How errors reach your application

Channel When Payload
onError callback Widget form submission or API call inside the iframe failed (http_code !== 200) See Widget error payload
onErrorActivationCode callback Activation-code check failed or code invalid (code === 1225) Same shape as widget error payload
hostError postMessage Invalid widget URL parameters (e.g. missing client_id) before the widget loads { validation_code, message }
Client-side validation Required fields or password rules fail before an API request is sent { validation_code, message } — validation_code is usually 422, or 1001 / 1002 for password mismatch / rules in activate-user
OIDC redirect (standalone) Silent auth (prompt=none) or account selection required Query params error and error_description on your redirect_uri
Standalone error page Token exchange, EIP callback, or authorization failure HTML page with errorCode (see Standalone page errors)
Network / parse failure Browser cannot reach the API or response is not JSON { success: false, http_code: 0 or status, code, message }

Widget error payload

Most widgets call your onError handler with a payload like:

{
    "success": false,
    "code": 1200,
    "http_code": 401,
    "message": "The security token is invalid.",
    "response": null
}
Field Description
success Always false for errors
code API message code when the error comes from the API; otherwise an HTTP status or frontend-specific value
http_code HTTP status code of the API response
message Human-readable text. If user-frontend has a translation for messages.error.{code}, that text is used; otherwise the API message is passed through unchanged
response Optional extra data (e.g. MFA challenge details). Usually null on error

For check activation code, use onErrorActivationCode instead of onError. Success is reported when http_code === 200 and code !== 1225.

For EIP config, onError receives { source: 'test' | 'save', data: { ...payload } }.

Use the language class config or per-widget messages / labels parameters to override displayed text inside the iframe. Map code values in your host application for custom error UI.

User-frontend errors

These errors are generated by user-frontend and do not use API message codes.

Configuration and authorization (widget iframe)

Key / identifier Default message When
configuration There is an error in your configuration Missing or invalid widget configuration (e.g. token, tenant, domain)
unsupported_response_type OAuth/OIDC response_type not supported SSO/OIDC widget authorize request
invalid_client Client validation failed (description in errorDescription) SSO/OIDC widget — invalid client_id or redirect URI
401_sso_error_title SSO login failed SSO login exception
401_sso Something went wrong during the SSO login process. Please try again or contact us. SSO login exception (description)
401_oidc_prompt_none_title Authentication required OIDC widget with prompt=none and no usable session
401_oidc_prompt_none The login cannot be displayed because the user is not authenticated and prompt=none was specified. OIDC widget with prompt=none (description)
409_multi_account_unsupported This feature does not currently support multiple accounts. Feature does not support multiple SSO accounts
mfaInvalidCode The code you entered is incorrect or has expired. Please try again. MFA verification failed in widget flow
401 You used an invalid username and password combination. Please try again, or use "Forgot password" to set a new password. Mapped login failure message (credentials)

Client-side validation (before API call)

Message key Default message
passwordRules Password does not meet the rules.
usernameRules Username does not meet the rules.
fillUsernamePassword Please fill in username and password.
fillPasswordTwice Please fill in the same password twice.
fillPasswordTwiceRule Please enter the identical password twice.
activationNotSet Activation code is not set.
fillUsername Please fill in the username.
fillActivationCode Please fill in the activation code.
fillEmail Please fill in your email address.
fillPasswordCode Please fill in the forgot password code.
eipConfig.fillAllFields Please fill in all fields.
eipConfig.errorWhileTesting An error occurred while testing EIP credentials.
eipConfig.errorWhileSaving An error occurred while saving EIP credentials.
loginWithEip.getLoginUrlUnprocessable Login is not possible. Please check your username and password and try again. Your account may not be configured for SSO login. Please contact your administrator.
loginWithEip.genericError Something went wrong while signing you in. Please try again later, or contact your administrator if the problem persists.
selectAccount.error An error occurred while selecting your account. Please try again.
mfaSetup.userNotFound User data not found.

Client-side validation posts { validation_code: 422, message: "..." } unless noted otherwise. Activate-user also uses validation_code: 1001 (passwords differ) and 1002 (password rules).

Standalone login page (HTTP status mapping)

Used on standalone OAuth/OIDC login pages when the login API returns a non-success HTTP status:

Key Default message (EN) HTTP status
network We can't reach the login service. Please check your internet connection and try again. connection failure
bad_request There's a problem with the information you entered. Please check your input and try again. 400, 422
invalid_credentials The email or password you entered is incorrect. Please try again. 401
invalid_mfa_code The code you entered is incorrect or has expired. Please request a new one and try again. MFA failure
forbidden You don't have permission to complete this action. Please contact support if you believe this is wrong. 403
too_many_requests Too many attempts. Please wait a moment before trying again. 429
service_unavailable The login service is temporarily unavailable. Please try again in a few minutes. 5xx
unknown Something went wrong. Please try again, or contact support if the problem persists. other

OIDC redirect errors (standalone)

When standalone OIDC authorization cannot complete silently, the user is redirected to your redirect_uri with:

error query param error_description When
login_required, interaction_required User authentication is required, but no active session was found and prompt=none was used. prompt=none without an active SSO session
account_selection_required, interaction_required Multiple accounts exist; account selection is required. prompt=none with multiple SSO accounts (SSO mode enabled)
select_account_error=1 Redirect to login page with account-selection error Account picker unavailable (e.g. SSO mode disabled), or the selected account's SSO session is no longer valid (revoked or expired) — see messages.selectAccount.error

Standalone page errors

errorCode Title Message
TOKEN_EXCHANGE_ERROR Authentication Error Failed to process authentication token.
EIP_LOGIN_ERROR EIP Authentication Error Failed to process EIP authentication.
USER_SUSPENDED Login not possible Your account is currently deactivated. Please contact your administrator to have it reactivated.
AUTHORIZATION_ERROR Authorization Error An error occurred during the authorization process.

API error codes (pass-through)

When a widget request fails, the response includes a numeric code and message. user-frontend replaces the message when a translation exists under messages.error.{code} (see Translated in UF column).

Authentication

Code Message (EN, API default) Translated in UF
700 Cannot authenticate with these user credentials. no — use API message
801 The service is currently in read-only mode. Please try again later. no — use API message

Password and input validation

Code Message (EN, API default) Translated in UF
1000 The password does not follow the policy: minimum 6 characters, at least one uppercase letter, one lowercase letter, one number. no — use API message
1001 The passwords have to be same. no — use API message
1002 You cannot use this link anymore to set your password as it is already set. Please use the "forgot password" link for this purpose. no — use API message
1003 Your password cannot be validated. no — use API message
1004 The given data was invalid. no — use API message
1005 Too many requests with this user sent. yes

User lifecycle

Code Message (EN, API default) Translated in UF
1100 User cannot be activated. no — use API message
1101 User created successfully. no — use API message
1102 User cannot be created. no — use API message
1103 User roles do not match product list. no — use API message
1104 User with preferred username already exists, please choose a different username. no — use API message
1105 User deleted no — use API message
1106 User cannot be deleted. no — use API message
1107 Activation mail has been resent. no — use API message
1108 Activation mail cannot been resent. no — use API message
1109 User updated. no — use API message
1110 User cannot be updated. no — use API message
1111 Invalid rights submitted. no — use API message
1112 User cannot set the tenant :param in capabilities. no — use API message
1113 User cannot set the domain :param in capabilities. no — use API message
1114 User cannot set the product :param in capabilities. no — use API message

Tokens and authorization

Code Message (EN, API default) Translated in UF
1200 The security token is invalid. yes
1201 The security token is expired. yes
1202 The security token is invalid. User not found. yes
1203 The security token is missing. yes
1204 The security token is valid. User not found. yes
1205 The access token is missing. yes
1206 The access token is invalid. yes
1207 The access token is expired. yes
1208 The refresh token is missing. yes
1209 The refresh token is invalid. yes
1210 The refresh token is expired. yes
1211 A new token pair cannot be created. yes
1212 The authentication process cannot be completed. yes
1213 Your subscription period has ended. Please contact customer service to renew your subscription. yes
1214 The user was already activated. yes
1215 If an account exists for this email address, you will shortly receive a link to set a new password. yes
1216 An error has occurred during initiation of forgot-password process. yes
1217 Forgot-password functionality is not available for given user. yes
1218 Password cannot be reset. yes
1219 The user is not allowed to change his password. yes
1220 The security token is valid. yes
1222 Email could not be sent because it's not allowed. no — use API message
1223 Email could not be sent because user has no email. no — use API message
1224 The activation code is valid. no — use API message
1225 The activation code is invalid. no — use API message
1226 The activation code is missing. no — use API message
1227 The username is already in use. no — use API message
1228 The activation code's valid date has been renewed. no — use API message
1229 There was no user submitted for authorization. no — use API message
1230 There are missing parameters for authorization. no — use API message
1231 The user has insufficient permissions. no — use API message
1232 The forgot password code has been created. no — use API message
1233 The username is invalid. no — use API message
1234 The forgot password code is missing. no — use API message
1235 The username is missing. no — use API message
1236 The username or forgot password code is invalid. no — use API message
1240 Given locale is not available for this domain. no — use API message
1241 Email update initiated, you will shortly receive a link to confirm the new email address. no — use API message
1242 Email address cannot be updated. no — use API message
1243 The email update token is invalid. no — use API message
1244 Email-update functionality is not available. Please contact customer service. no — use API message
1245 Tenant does not exist. no — use API message
1246 Tenant is virtual. no — use API message
1247 Domain is not specified. no — use API message
1248 Your account is currently deactivated. Please contact your administrator to have it reactivated. yes
1249 The oauth state is invalid. no — use API message
1250 The email address is already in use or on a blocklist. yes
1251 Cannot update locale for the given user source. no — use API message
1252 Cannot update user with the given user source. no — use API message
1253 Cannot delete user with the given user source. no — use API message
1260 No permission to send mails to the user. no — use API message
1261 No permission to send mails to a different email address. no — use API message
1262 The email update token is expired. no — use API message
1263 The email update token has already been used. no — use API message
1264 The activation token has already been used. The account is already activated. yes
1270 The link for providing an alternative email address is invalid. yes
1271 The link for providing an alternative email address has expired. yes
1272 An alternative email address has already been submitted for this link. yes

HTTP and API

Code Message (EN, API default) Translated in UF
1301 The user you are trying to delete still has active products. no — use API message

OAuth state

Code Message (EN, API default) Translated in UF
1410 OAuth state is missing. no — use API message
1411 OAuth state is invalid. no — use API message
1412 OAuth state is expired. no — use API message
1413 OAuth state is invalid. User not found. no — use API message

Federated authentication (account linking)

Code Message (EN, API default) Translated in UF
1501 The specified Identity Provider is not registered or does not exist. no — use API message
1510 Accounts were linked successfully. no — use API message
1511 Linking was not successful because the accounts were already linked. no — use API message
1512 The accounts could not be linked. no — use API message
1513 No federated account found for the given trusting user. no — use API message
1514 The trusting and trusted Identity Providers must be different. no — use API message
1515 No federation exists between the trusting and trusted Identity Providers. no — use API message
1516 The user from the trusting Identity Provider was not found. no — use API message
1517 The user from the trusting Identity Provider is not authorized to log in. no — use API message
1518 The user from the trusted Identity Provider was not found. no — use API message
1519 The user from the trusted Identity Provider is not authorized to log in. no — use API message
1520 Accounts have been unlinked successfully. no — use API message
1521 The accounts are not linked. no — use API message
1522 The accounts could not be unlinked. no — use API message

External identity provider (EIP)

Code Message (EN, API default) Translated in UF
1800 EIP sync history not found. no — use API message
1801 EIP not configured. no — use API message
1802 EIP configured. no — use API message
1803 EIP tested successfully. no — use API message
1804 EIP test failed. no — use API message
1805 EIP credentials stored successfully. no — use API message
1806 Failed to store EIP credentials. no — use API message
1807 Transform finished with one or more user-level failures; see errors in the response. no — use API message

Multi-factor authentication (MFA)

Code Message (EN, API default) Translated in UF
1901 MFA is not allowed for EntraID users. no — use API message
1902 Invalid MFA code. no — use API message
1903 MFA is already enabled for this user. no — use API message
1904 MFA is not enabled for this user. no — use API message
1905 MFA is not setup for this user. no — use API message
1906 MFA cannot be disabled when it is set as mandatory for this user. no — use API message
1907 MFA disabled successfully. no — use API message
1908 MFA enabled successfully! Your account is now protected. no — use API message
1909 MFA is not allowed for this domain. no — use API message
1910 MFA setup is required for this user. no — use API message
1911 MFA verification is required for this user. no — use API message
1912 Too many incorrect codes. Please wait a few minutes and log in again. yes
1913 MFA enable error occurred. no — use API message
1914 MFA disable error occurred. no — use API message
1915 MFA initialized successfully. no — use API message
1916 MFA initialization error occurred. no — use API message
1917 The MFA challenge token is missing. no — use API message
1918 The MFA challenge token is invalid. no — use API message
1919 MFA verified successfully. no — use API message

Note: Success responses also use API codes (e.g. 1101, 1224, 1908). Your onSuccess handler should inspect code and http_code rather than assuming any specific code always means failure.

Note: Codes not listed here usually indicate a platform-side configuration problem. Show a generic error and contact support.