> ## 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

## Dashboard Configuration

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

If users report delayed or missing OTP emails, see the [Email OTP delivery](/overview/troubleshooting/email-otp-delivery) troubleshooting guide.

## Prerequisites

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

## Usage

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={"system"}
    import {
      sendEmailOTP,
      verifyOTP
    } 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 = 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>

  <Tab title="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 [otp, setOtp] = useState('');

      const { mutate: sendEmailOTP, data: otpVerification, reset } = useSendEmailOTP();
      const { mutate: verifyOTP, isPending: isVerifying } = useVerifyOTP();

      if (otpVerification) {
        return (
          <div>
            <input
              value={otp}
              onChange={(e) => setOtp(e.target.value)}
              placeholder="Enter OTP"
            />
            <button onClick={() => verifyOTP({ otpVerification, otp })} 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>
      );
    }
    ```
  </Tab>
</Tabs>

## 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](/overview/troubleshooting/email-otp-delivery) troubleshooting guide.
</Tip>
