> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sublay.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Change Password

> Change the authenticated user's password

Changes the password for the currently authenticated user. The user must provide their current password for verification. Requires a valid access token in the `Authorization` header.

<Note>
  This endpoint is only available to users who signed up with email and password.
  OAuth-only users who have no password will receive a `400` error.
</Note>

## What a password change ends

A password change is what someone reaches for when they think their account has been taken, so it
ends sessions rather than only rotating a secret. In one transaction, the server:

* writes the new password;
* deletes **every push binding** this user holds, on every device, so notification content stops
  routing to a device an intruder may hold — except the device named by the optional `pushDevice`
  field below. Projects without the `push` bundle skip this step and are otherwise unaffected;
* destroys **every refresh-token family** for this user except the caller's own.

Either all three land or none does.

<Note>
  **The caller's own session survives, and nothing has to be sent for that.** The access token this
  route is authenticated by carries the id of the session it was minted from, so the server can tell
  which of the user's sessions is asking. The user stays signed in where they are standing; every
  other device must sign in again with the new password.

  A **service or master key** is not a session, so a call made with one has nothing to spare and
  ends every session for the user.
</Note>

<Warning>
  **Name your device or it stops notifying.** Nothing re-binds a device to push from its live
  session — repair happens on a cold start, an account switch or a token rotation, which on a
  resident mobile app can be days away. So a client that does not send `pushDevice` keeps its
  session but loses its notifications until one of those happens.
</Warning>

Existing **access** tokens are not revoked by this: an access token minted before the change keeps
working until it expires, up to 30 minutes. It is the refresh families that go, so no other device
can mint a new one.

## Body Parameters

<ParamField body="password" type="string" required>
  The user's current password.
</ParamField>

<ParamField body="newPassword" type="string" required>
  The new password. Must be different from the current password.
</ParamField>

<ParamField body="pushDevice" type="object">
  The physical device making the call, so **its** push binding survives while every other device
  this user is bound to loses theirs.

  The same shape [Register Device](/v8/api-reference/push-notifications/register-device) and
  [Sign Out](/v8/api-reference/auth/sign-out) take: `{ platform: "ios" | "android", token }` for
  native, `{ platform: "web", subscription }` for Web Push. It only ever spares a binding belonging
  to this user, so it cannot keep another account's binding alive on a shared device.

  Omit it and every binding for the user is deleted, this device's included.
</ParamField>

<ParamField body="userId" type="string">
  The acting user. **Service/master keys only** — an end-user token infers it from the access token
  and may not name a different user.
</ParamField>

## Response

<ResponseField name="success" type="boolean">
  `true` on success.
</ResponseField>

<ResponseField name="message" type="string">
  Confirmation message: `"Password updated successfully."`
</ResponseField>

## Error Responses

<AccordionGroup>
  <Accordion title="User Not Found — 403">
    ```json theme={null}
    {
      "error": "User not found.",
      "code": "auth/no-user-found"
    }
    ```
  </Accordion>

  <Accordion title="Not Password Authenticated — 400">
    ```json theme={null}
    {
      "error": "User is not authenticated with email and password.",
      "code": "auth/not-password-authenticated"
    }
    ```
  </Accordion>

  <Accordion title="Wrong Password — 401">
    ```json theme={null}
    {
      "error": "Incorrect password.",
      "code": "auth/wrong-password"
    }
    ```
  </Accordion>

  <Accordion title="Invalid Body — 400">
    ```json theme={null}
    { "error": "...", "code": "auth/invalid-body" }
    ```

    Returned when a required field is missing, when `newPassword` fails the password
    rules, when `newPassword` equals `password`, or when `pushDevice` is malformed —
    for example `platform: "ios"` with no `token`.
  </Accordion>

  <Accordion title="Missing User ID — 400">
    ```json theme={null}
    { "error": "Missing user ID", "code": "auth/missing-user-id" }
    ```

    Returned when a service/master key calls this route without naming a `userId`.
  </Accordion>

  <Accordion title="Acting As Another User — 403">
    ```json theme={null}
    { "error": "Unauthorized", "code": "auth/unauthorized" }
    ```

    Returned when an end-user token names a `userId` other than its own.
  </Accordion>

  <Accordion title="Server Error — 500">
    ```json theme={null}
    {
      "error": "Internal server error.",
      "code": "auth/server-error"
    }
    ```

    Nothing was committed — the password, the sessions and the push bindings are all
    as they were.
  </Accordion>
</AccordionGroup>

**Rate limit:** 5 requests per 5 minutes per IP. Exceeding it returns `429` with the plain-text message `Too many attempts to change password, please wait 5 minutes` and no `code`.

## See Also

* [`useAuth` hook](/v8/hooks/auth/use-auth) — `changePassword`
* [Built-in Auth guide](/v8/sdk/authentication/built-in)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.