useForgotPassword() is the headless password-recovery hook behind ForgotPassword. It starts the reset flow for an email address, verifies the OTP that comes back to the user, and then exchanges the reset token for a new session when the password is changed.
Usage
The following example shows a basic usage of useForgotPassword().
export default function ForgotPasswordFlow() { const { loading, forgotPassword, verifyOtp, resetPassword } = useForgotPassword(); async function run() { if (loading) { return; } await forgotPassword('jane@example.com'); const verification = await verifyOtp('jane@example.com', '123456'); if ('data' in verification) { await resetPassword(verification.data.token, 'NewPassword123!'); } } return <button onClick={run}>Reset password</button>;}
Return value
The hook returns the following fields and methods.
Whether the sign-in still requires a second factor.
How it works
The hook itself is linear: request a reset, verify the OTP, then exchange the returned reset token for a session with the new password.
The stock ForgotPassword component adds the screen state and navigation around this hook, but the hook itself does not manage any wizard step state.
A successful resetPassword() call can still return a session with unfinished sign-in attempts. The built-in UI checks for that and sends the user back into the sign-in flow when a second factor is still required.
The hook is email-based. Phone-based recovery and other recovery surfaces are not part of this contract.
When to use it
Examples
Start password recovery for an email address
export default function RequestPasswordReset() { const { loading, forgotPassword } = useForgotPassword(); async function sendCode() { if (loading) { return; } await forgotPassword('jane@example.com'); } return <button onClick={sendCode}>Send recovery code</button>;}
Verify the OTP and capture the reset token
export default function VerifyRecoveryCode() { const { loading, verifyOtp } = useForgotPassword(); async function verify() { if (loading) { return; } const result = await verifyOtp('jane@example.com', '123456'); if ('data' in result) { console.log(result.data.token); } } return <button onClick={verify}>Verify recovery code</button>;}
Reset the password and inspect the returned session
export default function CompletePasswordReset() { const { loading, resetPassword } = useForgotPassword(); async function complete() { if (loading) { return; } const result = await resetPassword('reset-token', 'NewPassword123!'); if ('data' in result && result.data.signin_attempts?.length) { const attempt = result.data.signin_attempts.at(-1); console.log(attempt?.current_step); } } return <button onClick={complete}>Set new password</button>;}