# Reset Password

Password reset is a two-phase flow for users who signed up with [email + password](/docs/products/embedded-wallet/swift/auth/email):

1. **Request** — `requestResetPassword` emails the user a link containing a reset `token`.
2. **Complete** — the user opens the link, your app reads the `token` from the deep link, and `resetPassword` sets the new password.

Both methods are `async throws` and return nothing.

:::note
This resets the user's **login** password. It does **not** change an embedded wallet's *password recovery* secret — that is managed separately via [recovery methods](/docs/configuration/recovery-methods) and [`setRecoveryMethod`](/docs/products/embedded-wallet/swift/wallet/recovery).
:::

## Request a reset email

```swift
import OpenfortSwift

func requestReset(email: String) async {
    do {
        try await OFSDK.shared.requestResetPassword(
            params: OFRequestResetPasswordParams(
                email: email,
                redirectUrl: "myapp://reset-password" // deep link your app handles
            )
        )
        // Tell the user to check their inbox.
    } catch {
        print("Couldn't send reset email: \(error.localizedDescription)")
    }
}
```

:::tip
`redirectUrl` must be a deep link your app handles (a custom scheme like `myapp://reset-password` or a Universal Link). The email opens this URL with a `token` query parameter — capture it in `.onOpenURL` (SwiftUI) or your `SceneDelegate`, then pass it to `resetPassword`.
:::

## Complete the reset

```swift
func completeReset(newPassword: String, token: String) async {
    do {
        try await OFSDK.shared.resetPassword(
            params: OFResetPasswordParams(password: newPassword, token: token)
        )
        // Password updated — send the user to the login screen.
    } catch {
        print("Failed to reset password: \(error.localizedDescription)")
    }
}
```

## Reading the token from the redirect

In SwiftUI, handle the incoming link and extract the `token`:

```swift
.onOpenURL { url in
    guard
        let comps = URLComponents(url: url, resolvingAgainstBaseURL: false),
        let token = comps.queryItems?.first(where: { $0.name == "token" })?.value
    else { return }

    Task { await completeReset(newPassword: newPassword, token: token) }
}
```

## Parameters

```swift
public struct OFRequestResetPasswordParams: OFCodableSendable {
    public let email: String
    public let redirectUrl: String
}

public struct OFResetPasswordParams: OFCodableSendable {
    public let password: String
    public let token: String // from the redirect link
}
```

## Related

* [Email authentication](/docs/products/embedded-wallet/swift/auth/email)
* [Wallet recovery methods](/docs/products/embedded-wallet/swift/wallet/recovery)
