Reset password
Auth
Reset password
Confirm a 6-digit reset code and set a new password.
POST
Reset password
Overview
Confirms a password reset by submitting the 6-digit code received viaPOST /forgot-password along with the new password.
On success:
- The OTP row is marked consumed.
- The new password is hashed with argon2id and persisted.
- All active refresh tokens for the user are revoked — every device gets logged out. This is intentional: if the reset request was attacker-driven, the legitimate user still controls their email, but we cannot trust any session that might predate the request.
POST /login with the new password to start a fresh session.
Same 5-attempt cap and INVALID_CODE / CODE_EXPIRED semantics as /verify-email.
Authentication
None required.Path parameters
None.Query parameters
None.Request body
| Field | Type | Required | Allowed values | Example |
|---|---|---|---|---|
email | string | yes | RFC 5322 valid, lowercased server-side | alice@example.com |
code | string | yes | Exactly 6 digits | 729048 |
newPassword | string | yes | 8..200 chars; must contain at least one letter AND one digit | n3wsecret9 |
Example payload
Response — 200 OK
| Field | Type | Notes | Example |
|---|---|---|---|
ok | boolean | Always true on success. Client should now call /auth/login with the new password. | true |
Example response
Error responses
| Status | Code | Meaning |
|---|---|---|
| 400 | VALIDATION_FAILED | Email malformed, code not 6 digits, or new password fails the policy. |
| 401 | INVALID_CODE | Wrong digits; attemptsUsed bumped. After 5 tries the row dies. |
| 401 | CODE_EXPIRED | No live reset OTP — either it expired (15-min TTL), was already consumed, or the attempt cap was hit. Restart from /forgot-password. |
Example error — 401 INVALID_CODE
Side effects
- Consumes the
otp_codesrow. - Updates
users.passwordHashto the new argon2id hash. - Updates all matching
refresh_tokensrows torevokedAt = now— every active session is killed.
See also
- Forgot password — get the reset code.
- Login — log in with the new password.