> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/supertokens/supertokens-core/llms.txt
> Use this file to discover all available pages before exploring further.

# Password Reset

> Generate and consume password reset tokens

The password reset flow consists of three endpoints that work together to allow users to reset their passwords securely.

## Generate Reset Token

### Endpoint

```
POST /recipe/user/password/reset/token
```

Generates a password reset token for a specific user.

### Request Body

<ParamField body="userId" type="string" required>
  The user's ID (can be external user ID or SuperTokens user ID)
</ParamField>

<ParamField body="email" type="string" required>
  The user's email address. Required for CDI >= 4.0.
</ParamField>

### Response

<ResponseField name="status" type="string" required>
  The status of the request. Either `OK` or `UNKNOWN_USER_ID_ERROR`.
</ResponseField>

<ResponseField name="token" type="string">
  The generated password reset token. Only present when status is `OK`.
</ResponseField>

### Response Examples

<ResponseExample>
  ```json Success theme={null}
  {
    "status": "OK",
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
  ```

  ```json Unknown User theme={null}
  {
    "status": "UNKNOWN_USER_ID_ERROR"
  }
  ```
</ResponseExample>

### Implementation Details

#### User ID Mapping

The endpoint supports both external and internal user IDs:

1. Accepts either external user ID or SuperTokens user ID
2. If user ID mapping exists, converts to internal SuperTokens user ID
3. Generates token using the internal user ID

#### Token Generation

For CDI >= 4.0:

* Requires both user ID and email
* Token includes email validation
* More secure against user enumeration

For CDI \< 4.0:

* Only requires user ID
* Uses legacy token generation method

#### Multi-tenancy

The endpoint is tenant-specific:

* Verifies Email Password is enabled for the tenant
* User must belong to the tenant
* Token is scoped to the tenant

***

## Consume Reset Token

### Endpoint

```
POST /recipe/user/password/reset/token/consume
```

Consumes a password reset token to retrieve the associated user information. This endpoint validates the token and returns the user details, but does not actually reset the password.

<Note>
  This endpoint only validates the token and returns user information. To actually reset the password, use the [Reset Password endpoint](#reset-password-deprecated) with the token and new password.
</Note>

### Request Body

<ParamField body="token" type="string" required>
  The password reset token to consume
</ParamField>

### Response

<ResponseField name="status" type="string" required>
  The status of the request. Either `OK` or `RESET_PASSWORD_INVALID_TOKEN_ERROR`.
</ResponseField>

<ResponseField name="userId" type="string">
  The user's ID (external user ID if mapped, otherwise SuperTokens user ID). Only present when status is `OK`.
</ResponseField>

<ResponseField name="email" type="string">
  The user's email address. Only present when status is `OK`.
</ResponseField>

### Response Examples

<ResponseExample>
  ```json Success theme={null}
  {
    "status": "OK",
    "userId": "fa7a0841-b533-4478-95533-0fde890c3d37",
    "email": "user@example.com"
  }
  ```

  ```json Invalid Token theme={null}
  {
    "status": "RESET_PASSWORD_INVALID_TOKEN_ERROR"
  }
  ```
</ResponseExample>

### Implementation Details

#### Token Validation

The endpoint validates that:

* Token exists and is valid
* Token has not expired
* Token has not been consumed already

#### User ID Mapping

After consuming the token:

1. Retrieves the internal SuperTokens user ID from the token
2. Looks up user ID mapping if it exists
3. Returns the external user ID in the response (if mapped)

#### Multi-tenancy

The endpoint is tenant-specific:

* Token must be valid for the tenant
* User must belong to the tenant

***

## Reset Password (Deprecated)

<Warning>
  This endpoint is deprecated. Use a combination of [Consume Reset Token](#consume-reset-token) and a direct password update instead.
</Warning>

### Endpoint

```
POST /recipe/user/password/reset
```

Resets a user's password using a valid password reset token.

### Request Body

<ParamField body="method" type="string" required>
  The reset method. Must be `"token"`.
</ParamField>

<ParamField body="token" type="string" required>
  The password reset token
</ParamField>

<ParamField body="newPassword" type="string" required>
  The new password. Cannot be an empty string.
</ParamField>

### Response

<ResponseField name="status" type="string" required>
  The status of the request. Either `OK` or `RESET_PASSWORD_INVALID_TOKEN_ERROR`.
</ResponseField>

<ResponseField name="userId" type="string">
  The user's ID (external user ID if mapped, otherwise SuperTokens user ID). Only present when status is `OK` and CDI >= 2.12.
</ResponseField>

### Response Examples

<ResponseExample>
  ```json Success theme={null}
  {
    "status": "OK",
    "userId": "fa7a0841-b533-4478-95533-0fde890c3d37"
  }
  ```

  ```json Invalid Token theme={null}
  {
    "status": "RESET_PASSWORD_INVALID_TOKEN_ERROR"
  }
  ```
</ResponseExample>

### Implementation Details

#### Password Validation

The API validates that:

* New password is not an empty string
* Additional password strength requirements should be enforced at the application level

#### Token Consumption

The token is consumed during the password reset, meaning:

* Each token can only be used once
* After successful reset, the token is invalidated
* Token cannot be reused

#### User ID Mapping

After resetting the password:

1. Uses the internal SuperTokens user ID for the reset operation
2. Looks up user ID mapping if it exists
3. Returns the external user ID in the response (if mapped)

***

## Password Reset Flow

The complete password reset flow typically works as follows:

1. **User requests password reset**
   * Your application collects the user's email
   * You look up the user ID from the email
   * Call [Generate Reset Token](#generate-reset-token) with the user ID and email

2. **Send reset email**
   * Send the token to the user's email
   * Include a link to your password reset page with the token

3. **User clicks reset link**
   * Your application receives the token from the URL
   * Optionally call [Consume Reset Token](#consume-reset-token) to validate the token
   * Show password reset form to the user

4. **User submits new password**
   * Your application collects the new password
   * Call [Reset Password](#reset-password-deprecated) (deprecated) or use a direct password update API
   * Show success message and redirect to login

## Security Considerations

### Token Expiration

Password reset tokens have a limited lifetime:

* Configure token expiration time in your SuperTokens configuration
* Tokens are automatically invalidated after expiration
* Users must request a new token if theirs expires

### Token Storage

Password reset tokens:

* Are cryptographically secure
* Should be transmitted over HTTPS only
* Should not be logged or stored in your application
* Expire after use or time limit

### Rate Limiting

Consider implementing rate limiting for:

* Token generation (prevent email flooding)
* Token consumption (prevent brute force attacks)
* Password reset completion

### Email Verification

For enhanced security:

* Only allow password reset for verified email addresses
* Require email verification before generating reset token
* Send notification email when password is changed

## Error Cases

### UNKNOWN\_USER\_ID\_ERROR

Returned by Generate Reset Token when:

* User ID does not exist
* User does not belong to the tenant
* User does not have email/password login method

### RESET\_PASSWORD\_INVALID\_TOKEN\_ERROR

Returned by Consume Reset Token and Reset Password when:

* Token does not exist
* Token has expired
* Token has already been consumed
* Token format is invalid

### Bad Request (400)

Returned when:

* Required fields are missing
* Password is an empty string
* Method is not "token" (for Reset Password endpoint)
* Invalid JSON in request body

### Internal Server Error (500)

Returned when:

* Database query fails
* Tenant or app not found
* Permission errors
* Other internal errors

## Code References

* Generate Token: [GeneratePasswordResetTokenAPI.java:57](https://github.com/supertokens/supertokens-core/blob/master/src/main/java/io/supertokens/webserver/api/emailpassword/GeneratePasswordResetTokenAPI.java#L57)
* Consume Token: [ConsumeResetPasswordAPI.java:55](https://github.com/supertokens/supertokens-core/blob/master/src/main/java/io/supertokens/webserver/api/emailpassword/ConsumeResetPasswordAPI.java#L55)
* Reset Password: [ResetPasswordAPI.java:57](https://github.com/supertokens/supertokens-core/blob/master/src/main/java/io/supertokens/webserver/api/emailpassword/ResetPasswordAPI.java#L57)
