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

# Authenticate with Email

## Console Configuration

Simply toggle on "Email" in [the Log in & User Profile section of the Dynamic Console](https://console.dynamic.xyz/dashboard/log-in-user-profile).

If users report delayed or missing OTP emails, see the [Email OTP delivery](https://docs.dynamic.xyz/docs/get-started/troubleshooting/email-otp-delivery.md) troubleshooting guide.

## Prerequisites

Before this: create and initialize a Dynamic client (see [Creating a Dynamic Client](https://docs.dynamic.xyz/docs/javascript/reference/client/create-dynamic-client.md), [Initializing the Dynamic Client](https://docs.dynamic.xyz/docs/javascript/reference/client/initialize-dynamic-client.md)).

## Usage

> [tab] JavaScript
>
> ```javascript theme={"system"}
> import {
>   sendEmailOTP,
>   verifyOTP,
>   type OTPVerification
> } from '@dynamic-labs-sdk/client';
>
> // With the user's email, call sendEmailOTP to get the otpVerification
> // Then, once the user inputs the OTP code, call verifyOTP to verify it and complete the authentication
>
> let otpVerification: OTPVerification | null = null;
>
> const signInWithEmail = async () => {
>   // Replace 'test@test.com' with the user's email address
>   otpVerification = await sendEmailOTP({ email: 'test@test.com' });
>   // Store the otpVerification for later use with the verifyOTP function
> };
>
> const handleVerifyOTP = async () => {
>   // Use the same otpVerification object that you got from the sendEmailOTP function
>   // Replace '123456' with the OTP code entered by the user
>   await verifyOTP({ otpVerification, verificationToken: '123456' });
> };
> ```

> [tab] React
>
> `useSendEmailOTP` returns the `otpVerification` object as its `data`; pass it to `useVerifyOTP` to complete the flow.
>
> ```tsx theme={"system"}
> import { useSendEmailOTP, useVerifyOTP } from '@dynamic-labs-sdk/react-hooks';
> import { useState } from 'react';
>
> function EmailSignIn() {
>   const [email, setEmail] = useState('');
>   const [verificationToken, setVerificationToken] = useState('');
>
>   const { mutate: sendEmailOTP, data: otpVerification, reset } = useSendEmailOTP();
>   const { mutate: verifyOTP, isPending: isVerifying } = useVerifyOTP();
>
>   if (otpVerification) {
>     return (
>       <div>
>         <input
>           value={verificationToken}
>           onChange={(e) => setVerificationToken(e.target.value)}
>           placeholder="Enter OTP"
>         />
>         <button onClick={() => verifyOTP({ otpVerification, verificationToken })} disabled={isVerifying}>
>           Verify
>         </button>
>         <button onClick={() => reset()}>Back</button>
>       </div>
>     );
>   }
>
>   return (
>     <div>
>       <input
>         type="email"
>         value={email}
>         onChange={(e) => setEmail(e.target.value)}
>         placeholder="Email address"
>       />
>       <button onClick={() => sendEmailOTP({ email })}>Send OTP</button>
>     </div>
>   );
> }
> ```

> [!WARNING]
>
> If a user is already signed in, `verifyOTP` links the email to that user instead of signing in. If the project requires [step-up authentication](https://docs.dynamic.xyz/docs/auth/step-up-auth.md) to link an email, verification fails with HTTP 403 and "Elevated access token required". If you intend to sign a user in, call `logout()` before `sendEmailOTP` (or `useLogout` in React).
>
> ```javascript theme={"system"}
> import { logout, sendEmailOTP } from '@dynamic-labs-sdk/client';
>
> await logout();
> const otpVerification = await sendEmailOTP({ email: 'test@test.com' });
> ```
>
> In React, sign the user out with `useLogout` before sending the code:
>
> ```tsx theme={"system"}
> import { useLogout, useSendEmailOTP } from '@dynamic-labs-sdk/react-hooks';
>
> const { mutateAsync: logout } = useLogout();
> const { mutateAsync: sendEmailOTP } = useSendEmailOTP();
>
> const signInWithEmail = async (email: string) => {
>   await logout();
>   return sendEmailOTP({ email });
> };
> ```

## Rate Limits

Email verification is subject to the following rate limits:

* 3 attempts per 10 minutes per email address

This is in place to protect deliverability of emails and to prevent abuse.

> [!TIP]
>
> If users report delayed or missing OTP emails, see the [Email OTP delivery](https://docs.dynamic.xyz/docs/get-started/troubleshooting/email-otp-delivery.md) troubleshooting guide.


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