Email Magic Link Authentication

Email magic link authentication allows you to log in and sign up users using an email address. Your users will receive a link in their inbox which will redirect them to your site (configured in the dashboard) to complete login.

We recommend using the OTP email flow instead, as it is more reliable across different browser environments. OTP flows have also been shown to have up to a 3x higher conversion rate and a 10-second faster flow compared to magic link.

For setting up the OTP flow, see Email OTP Authentication.

For setting up an account config, see the Signer Quickstart.

Authenticate a user

1import { signer } from "./signer";
2
3// send the email
4// resolves when the user is fully authenticated (magic link + optional MFA), even if completion happens in another tab/window
5await signer.authenticate({
6 type: "email",
7 emailMode: "magicLink",
8 email: "[email protected]",
9});
10
11// later once the user has clicked the link
12const url = new URL(window.location.href);
13const bundle = url.searchParams.get("bundle");
14if (!bundle) {
15 throw new Error("No bundle found in URL");
16}
17
18// resolves when the user is fully authenticated (magic link + optional MFA), even if completion happens in another tab/window
19await signer.authenticate({
20 type: "email",
21 bundle,
22});

Track Authentication Status

Use signer.on("statusChanged", callback) and the AlchemySignerStatus enum to respond to OTP/MFA prompts and completion:

1import { signer } from "./signer";
2import { AlchemySignerStatus } from "@account-kit/signer";
3
4signer.on("statusChanged", (status) => {
5 switch (status) {
6 case AlchemySignerStatus.AWAITING_EMAIL_AUTH:
7 // show OTP input UI
8 break;
9 case AlchemySignerStatus.AWAITING_MFA_AUTH:
10 // show TOTP input UI
11 break;
12 case AlchemySignerStatus.CONNECTED:
13 // authentication complete
14 break;
15 }
16});