Passwords

Forte supports password-based sign-in alongside OTP and Google OAuth. A user can set a password during sign-up or later, then sign in with any of their verified contact methods plus that password. OTP login stays available even without a password, so users always have a recovery path.

Client-side API

The flows on this page are part of Forte's client-side API. Call the Users methods from your frontend — Forte sets the Forte-User-Session-Token cookie on successful responses. Never call these methods from code that holds FORTE_API_TOKEN.

Enable password sign-in

Toggle Password login on under your project's authentication settings. While there, choose:

  • Strength rules — shortest allowed length plus optional requirements for uppercase letters, lowercase letters, digits, and symbols.
  • Reset behavior — either Send a new password or Send a reset link (see Reset a password below).

When reset behavior is Send a reset link, you must also set a reset link target URL — the page on your site that handles the new-password form.

Set password strength rules

When set, strength rules apply on:

  • Sign-up (the password field on forte.users.register),
  • Self-service change (forte.users.changePassword),
  • Resets that complete with a user-chosen password (forte.users.completePasswordReset),
  • Admin force-set in sandbox projects.

Forte enforces a hard floor of 6 characters and a ceiling of 128. Project-configured minLength is clamped into that range.

Sign up with a password

Pass password on the register call. The user is registered with the password already set — they can sign in with it as soon as their contact method is verified.

typescript
const result = await forte.users.register({
  projectId,
  email: "alice@example.com",
  password: "correct-horse-battery-staple",
});
 
// result.userObject.hasPassword === true
// (userObject is omitted when mfaStatus is pending — see MFA)

Errors:

  • PASSWORD_LOGIN_NOT_ENABLED — the project doesn't have password login turned on yet.
  • PASSWORD_TOO_WEAK — the password doesn't meet the project's strength rules.

Sign in with a password

forte.users.passwordLogin takes a single contactValue — Forte detects whether it's an email or phone number. The contact method must be verified. A user who set a password but never verified must first verify — for example, by signing in once with OTP or completing a password reset, both of which verify the contact (see Authentication → Edge cases and recovery).

typescript
const result = await forte.users.passwordLogin({
  projectId,
  passwordLoginRequest: {
    contactValue: "alice@example.com",
    password: "correct-horse-battery-staple",
  },
});
 
// result.userObject — the authenticated user (omitted while MFA is pending)
// result.sessionToken.sessionToken — set automatically as a cookie

Errors:

  • INVALID_CREDENTIALS — wrong password, no user, or the contact method isn't verified. Forte returns the same error for all three (and matches response timing) to prevent account enumeration.
  • PASSWORD_LOGIN_NOT_ENABLED — the project doesn't have password login turned on.
  • THROTTLED — too many failed attempts from your IP within 15 minutes. Try again later.

Change a password

A signed-in user can change their own password by calling forte.users.changePassword. The session is already proof of identity, so currentPassword is optional — a signed-in user does not have to re-enter their existing password. A first-time set, when the user has no password yet, is one case of this.

If you do send currentPassword, Forte validates it against the stored password and rejects the change with INVALID_CREDENTIALS when it doesn't match. Pass it when you want to re-confirm identity before a sensitive change; omit it for a frictionless "set a new password" flow.

typescript
// Signed in already — currentPassword is optional
await forte.users.changePassword({
  projectId,
  changePasswordRequest: {
    newPassword: "new-stronger-pw",
  },
});
 
// Optionally pass currentPassword to re-confirm identity —
// Forte returns INVALID_CREDENTIALS if it doesn't match
await forte.users.changePassword({
  projectId,
  changePasswordRequest: {
    currentPassword: "old-pw",
    newPassword: "new-stronger-pw",
  },
});

On success, the user's current session stays valid; every other session for that user is revoked.

Reset a password

When a user clicks "Forgot password?" your frontend calls forte.users.requestPasswordReset({ contactValue }). Forte looks up the user from the supplied value and sends a reset notification to their first verified contact method.

If the account has no verified contact method yet and the value matches one of its unverified contacts, Forte sends the reset to that contact instead and verifies it when the reset is acted on — this is how a user who registered but never verified recovers. If the account already has a verified contact method, an unverified contact on that account is never used as a reset target; this is a deliberate account-takeover protection. See Authentication → Edge Cases and Recovery.

The notification's contents depend on your project's reset mode:

Mode 1: send a new password

Forte generates a 16-character alphanumeric password, sets it on the user (revoking all existing sessions), and emails or texts it to them. The user then signs in with that generated password. Your project's email template should tell the user to change it. If the reset targeted an unverified contact (only possible on an account with no verified owner), that contact is marked verified when the new password is sent, so the user can sign in with it right away.

Forte mints a single-use reset token (30-minute expiry) and sends a link in the form:

javascript
https://app.example.com/reset-password?pwdResetToken=<token>

Your frontend reads pwdResetToken from the query string, asks the user for a new password, and calls forte.users.completePasswordReset:

typescript
const params = new URLSearchParams(window.location.search);
const token = params.get("pwdResetToken");
 
const result = await forte.users.completePasswordReset({
  projectId,
  completePasswordResetRequest: {
    token,
    newPassword: "the-user-chose-this",
  },
});
 
// User is signed in immediately — session token is set in the cookie. If the
// project enforces MFA, mfaStatus may instead be pending and userObject omitted.
console.log("Welcome back,", result.userObject?.fullName);

If the token has expired, been used, or has more than 5 failed attempts, Forte returns INVALID_RESET_TOKEN. The new password must meet the project's strength rules or Forte returns PASSWORD_TOO_WEAK. If the reset link was sent to an unverified contact (only possible on an account with no verified owner), completing the reset verifies that contact.

When the project enforces MFA, the email that received the reset link is excluded from the second-factor step whenever the user has any other usable factor; it stays accepted only as a last resort for a user with nothing else (see MFA). Encourage users to verify a second contact method or enroll an authenticator so account recovery never depends on a single inbox.

Request behavior

requestPasswordReset always returns 204 whether the user exists, the contact method is verified, or the request was throttled — preventing account enumeration. Forte rate-limits each user to one request every 60 seconds.

Customize the reset notification

The reset notification has one template — Forte renders either {{newPassword}} or {{resetUrl}} depending on the active mode. Write a single template that handles both modes with Mustache sections:

mustache
{{#newPassword}}Your new password is {{newPassword}}. Please change it after signing in.{{/newPassword}}
{{#resetUrl}}Reset your password: {{resetUrl}} (expires in 30 minutes).{{/resetUrl}}

Available variables: {{newPassword}}, {{resetUrl}}, {{projectName}}, {{userFullName}}, {{contactValue}}.

Customize the subject, HTML body, and SMS body under NotificationsPassword reset in project settings. Leave fields blank to use Forte's built-in defaults.

Admin operations

In the console, open a user's detail page to see the Authentication card:

  • Reset password — runs the same flow as forte.users.requestPasswordReset but on behalf of an administrator. Available on every project.
  • Force set password — sandbox projects only. Lets an administrator type a specific password directly. Revokes all the user's existing sessions. Useful for end-to-end testing.

Both actions are audited in the user's action logs (PASSWORD_ADMIN_RESET and PASSWORD_ADMIN_FORCE_SET).

Error codes

Error codeMeaning
PASSWORD_LOGIN_NOT_ENABLEDPassword login is off on this project.
PASSWORD_TOO_WEAKPassword fails the project's strength rules.
INVALID_CREDENTIALSLogin password mismatch, no user/verified contact for the supplied value, or a currentPassword that doesn't match when changing a password.
INVALID_RESET_TOKENReset token is missing, expired, consumed, or has too many failed attempts.
PASSWORD_CONFIG_INVALIDProject's password configuration isn't valid (for example, a missing reset mode).
PASSWORD_RESET_TARGET_URL_REQUIREDReset mode is Send a reset link but no target URL is set.
SANDBOX_MODE_REQUIREDTried to force-set a password on a non-sandbox project.
THROTTLEDToo many recent failed login attempts from this IP.

Next steps

Search

Search documentation and console pages