---
title: "Reset Password"
method: POST
path: "/api/v1/auth/reset-password"
tags: ["auth"]
---

# Reset Password

`POST /api/v1/auth/reset-password`

## Request

- Base URL: `https://api.badgeia.com`
- URL: `https://api.badgeia.com/api/v1/auth/reset-password`
- Auth: none declared

Complete a password reset (SEC-AUTH-013).

Validates the token (exists, not expired, not used), enforces the signup
password-strength policy (done by the schema → 422 on weak), sets the new
hash, marks the token used (single-use), and **revokes every refresh-token
chain for the user** so any session an attacker established with the old
password is killed. Emits `password_reset_completed`.

#1414 (security review F2): a completed reset also clears the account's
sign-in lockout counter. Anyone who knows an account's email can keep its
password sign-in locked by sending five wrong passwords every window; proving
mailbox control is the owner's way back in. The per-address counter is
left alone, as on a successful sign-in.

Any token failure (missing / expired / already used) → ONE opaque 400 so
a prober can't distinguish the cases.

## Request body

- ResetPasswordRequest: Body for POST /auth/reset-password. `new_password` reuses the signup strength policy via password_service.validate_password_strength so a reset can never set a weaker password than signup allows. A weak password → 422 (Pydantic surfaces the ValueError message). The token itself is validated in the handler (existence / expiry / single-use), not here.
  - `token` string, required
  - `new_password` string, required

## Response `200`

Successful Response

- object

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/badgeia/apis/badge.md) · [All operations](https://skmtc.dev/badgeia/apis/badge/llms.txt) · [OpenAPI document](https://skmtc.dev/badgeia/apis/badge/revisions/7e7f7fee8b77?raw)
