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

# Email OTP

> Authenticate users with one-time passcodes sent to their email address

# Email Authentication

MoonKey enables users to login to your application with email-based one-time passcodes (OTP). With email authentication, your application can verify ownership of a user's email address without requiring passwords.

<Tip>
  Enable email authentication in the [MoonKey Dashboard](https://dashboard.moonkey.fun) under **Login Methods** before implementing this feature.
</Tip>

<Info>
  For the complete and latest API reference, including all configuration options, check the [@moon-key/react-auth](https://www.npmjs.com/package/@moon-key/react-auth) npm package.
</Info>

## Using the React SDK

To authenticate your users, use the `useMoonKey` hook and call the `start()` method to initiate the authentication flow.

### Import

```typescript theme={null}
import { useMoonKey } from '@moon-key/react-auth';
```

## Configuration

### Email OTP Configuration

You can customize the email OTP flow by passing an `EmailOtpConfig` object to the `MoonKeyProvider`:

<ParamField path="skipVerifiedSuccess" type="boolean">
  Skip the success screen after successful verification
</ParamField>

<ParamField path="expiresIn" type="number">
  OTP expiration time in seconds (default: 600 = 10 minutes)
</ParamField>

<ParamField path="verifiedDisplayTime" type="number">
  How long to display the success message in milliseconds
</ParamField>

<ParamField path="verifyEmailTitle" type="string">
  Custom title for the email verification screen
</ParamField>

<ParamField path="verifyEmailResendTitle" type="string">
  Custom text for the resend code button
</ParamField>

<ParamField path="resendCodeTime" type="number">
  Time in seconds before resend is allowed (default: 60)
</ParamField>

<ParamField path="verifiedNewUserMessage" type="string">
  Custom message shown to new users after verification
</ParamField>

<ParamField path="verifiedExistingUserMessage" type="string">
  Custom message shown to existing users after verification
</ParamField>

<ParamField path="verifiedSuccessMessage" type="string">
  Custom success message after verification
</ParamField>

### Example Configuration

```tsx theme={null}
import { MoonKeyProvider } from '@moon-key/react-auth';

export default function App() {
  return (
    <MoonKeyProvider
      publishableKey="your_publishable_key"
      config={{
        loginMethods: ['email', 'google'],
        emailOtp: {
          skipVerifiedSuccess: false,
          expiresIn: 600,
          verifiedDisplayTime: 3000,
          verifyEmailTitle: 'Verify your email',
          verifyEmailResendTitle: 'Resend code',
          resendCodeTime: 60,
          verifiedNewUserMessage: 'Welcome! Your account has been created.',
          verifiedExistingUserMessage: 'Welcome back!',
          verifiedSuccessMessage: 'Email verified successfully'
        }
      }}
    >
      {/* Your app */}
    </MoonKeyProvider>
  );
}
```

## Using the start() method

### Start authentication flow

Initiate the authentication flow with email or other login methods:

```typescript theme={null}
start: (params?: {
  loginMethods?: ('email' | 'google' | 'apple' | 'wallet')[];
  prefill?: { type: 'email' | 'phone'; value: string };
  disableSignup?: boolean;
  walletChainType?: 'ethereum' | 'solana' | 'ethereum-or-solana';
}) => void
```

#### Parameters

<ParamField path="loginMethods" type="array">
  Array of login methods to show. Options: `'email'`, `'google'`, `'apple'`, `'wallet'`. If not provided, uses login methods configured in the provider.
</ParamField>

<ParamField path="prefill" type="object">
  Pre-fill the authentication form with an email or phone number.

  * `type`: Either `'email'` or `'phone'`
  * `value`: The email address or phone number to prefill
</ParamField>

<ParamField path="disableSignup" type="boolean">
  If true, prevents new user signups and only allows existing users to login.
</ParamField>

<ParamField path="walletChainType" type="string">
  Specify which wallet type(s) to support. Options: `'ethereum'`, `'solana'`, or `'ethereum-or-solana'`.
</ParamField>

#### Returns

<ResponseField name="void" type="void">
  Opens the authentication modal/flow. No return value.
</ResponseField>

### Basic Usage

```tsx theme={null}
import { useMoonKey } from '@moon-key/react-auth';

export default function LoginButton() {
  const { start, isAuthenticated, user } = useMoonKey();

  if (isAuthenticated) {
    return <div>Welcome, {user.email}!</div>;
  }

  return (
    <button onClick={() => start()}>
      Login
    </button>
  );
}
```

### Email-only login

To show only email authentication:

```tsx theme={null}
import { useMoonKey } from '@moon-key/react-auth';

export default function EmailOnlyLogin() {
  const { start, isAuthenticated, user } = useMoonKey();

  if (isAuthenticated) {
    return (
      <div>
        <h2>Welcome, {user.email}!</h2>
        <p>You're successfully logged in.</p>
      </div>
    );
  }

  return (
    <button onClick={() => start({ loginMethods: ['email'] })}>
      Login with Email
    </button>
  );
}
```

### Customizing Messages and Behavior

Here's an example with custom configuration for a better user experience:

```tsx theme={null}
import { MoonKeyProvider } from '@moon-key/react-auth';

export default function App() {
  return (
    <MoonKeyProvider
      publishableKey="your_publishable_key"
      config={{
        loginMethods: ['email', 'google'],
        emailOtp: {
          // Skip the success screen for faster flow
          skipVerifiedSuccess: true,
          
          // Custom title for verification
          verifyEmailTitle: 'Check your inbox',
          
          // Shorter resend time for better UX
          resendCodeTime: 30,
          
          // Custom messages
          verifiedNewUserMessage: '🎉 Welcome! Your account is ready.',
          verifiedExistingUserMessage: '👋 Welcome back!',
          verifiedSuccessMessage: '✓ Email verified'
        }
      }}
    >
      {/* Your app */}
    </MoonKeyProvider>
  );
}
```

### Prefill email address

Prefill the email input when you know the user's email:

```tsx theme={null}
import { useMoonKey } from '@moon-key/react-auth';

export default function LoginWithPrefill({ userEmail }: { userEmail: string }) {
  const { start } = useMoonKey();

  return (
    <button 
      onClick={() => start({
        loginMethods: ['email'],
        prefill: { type: 'email', value: userEmail }
      })}
    >
      Login as {userEmail}
    </button>
  );
}
```

### Login-only (no signup)

Prevent new user signups and only allow existing users to login:

```tsx theme={null}
import { useMoonKey } from '@moon-key/react-auth';

export default function LoginOnly() {
  const { start } = useMoonKey();

  return (
    <button 
      onClick={() => start({
        loginMethods: ['email', 'google'],
        disableSignup: true
      })}
    >
      Login (Existing Users)
    </button>
  );
}
```

### Multiple login methods

Show multiple authentication options:

```tsx theme={null}
import { useMoonKey } from '@moon-key/react-auth';

export default function MultiMethodLogin() {
  const { start } = useMoonKey();

  return (
    <button 
      onClick={() => start({
        loginMethods: ['email', 'google', 'apple', 'wallet'],
        walletChainType: 'ethereum-or-solana'
      })}
    >
      Login
    </button>
  );
}
```

## Using the REST API

For custom implementations or backend integration, use the MoonKey REST API directly.

### Send Email OTP

Send a one-time passcode to the user's email:

```bash theme={null}
curl -X POST "https://api.moonkey.fun/v1/auth/otps/email/send" \
  -H "Authorization: Bearer sk_test_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com"
  }'
```

#### Response

```json theme={null}
{
  "success": true,
  "message": "OTP sent successfully"
}
```

### Verify Email OTP

Verify the OTP code and authenticate the user:

```bash theme={null}
curl -X POST "https://api.moonkey.fun/v1/auth/otps/verify" \
  -H "Authorization: Bearer sk_test_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "code": "123456",
    "session_expires_in": 10080
  }'
```

#### Parameters

| Parameter            | Type   | Required | Description                                           |
| -------------------- | ------ | -------- | ----------------------------------------------------- |
| `email`              | string | Yes      | The user's email address                              |
| `code`               | string | Yes      | The 6-digit OTP code                                  |
| `session_expires_in` | number | No       | Session duration in minutes (default: 10080 = 7 days) |

#### Response

```json theme={null}
{
  "session_token": "session_abc123...",
  "session_jwt": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": "user_xyz789",
    "email": "user@example.com",
    "created_at": 1704067200,
    "updated_at": 1704067200
  },
  "session": {
    "id": "session_abc123",
    "user_id": "user_xyz789",
    "expires_at": 1704672000,
    "created_at": 1704067200
  }
}
```

### Backend Implementation Example

```javascript theme={null}
// Express.js backend example
import express from 'express';

const app = express();
app.use(express.json());

// Send OTP endpoint
app.post('/api/auth/send-otp', async (req, res) => {
  const { email } = req.body;

  try {
    const response = await fetch('https://api.moonkey.fun/v1/auth/otps/email/send', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.MOONKEY_SECRET_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ email })
    });

    if (!response.ok) {
      throw new Error('Failed to send OTP');
    }

    res.json({ success: true });
  } catch (error) {
    res.status(500).json({ error: 'Failed to send OTP' });
  }
});

// Verify OTP endpoint
app.post('/api/auth/verify-otp', async (req, res) => {
  const { email, code } = req.body;

  try {
    const response = await fetch('https://api.moonkey.fun/v1/auth/otps/verify', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${process.env.MOONKEY_SECRET_KEY}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        email,
        code,
        session_expires_in: 10080 // 7 days
      })
    });

    if (!response.ok) {
      return res.status(401).json({ error: 'Invalid OTP code' });
    }

    const data = await response.json();
    
    // Return session credentials to client
    res.json({
      session_token: data.session_token,
      session_jwt: data.session_jwt,
      user: data.user
    });
  } catch (error) {
    res.status(500).json({ error: 'Verification failed' });
  }
});
```

## Configuration

### Enable email authentication

1. Log in to the [MoonKey Dashboard](https://dashboard.moonkey.fun)
2. Navigate to **Login Methods**
3. Enable **Email OTP**
4. Save your changes

### Customize email templates

You can customize the OTP email template in the dashboard:

1. Navigate to **Email Templates**
2. Select **OTP Email**
3. Customize the subject, content, and styling
4. Preview and save

## Best Practices

### Security

* **Rate limiting**: Implement rate limits on OTP sending to prevent abuse
* **Code expiration**: OTP codes expire after 10 minutes
* **Maximum attempts**: Limit verification attempts to prevent brute force
* **Secure transmission**: Always use HTTPS for API calls

### User Experience

* **Clear instructions**: Tell users where to find the code
* **Resend option**: Allow users to request a new code if needed
* **Loading states**: Show loading indicators during API calls
* **Error handling**: Provide clear error messages

### Implementation

The MoonKey SDK handles the entire email OTP flow automatically, including:

* Sending the OTP code
* Displaying the code input form
* Verifying the code
* Managing resend functionality with countdown timer
* Error handling and validation

You can customize this behavior using the `emailOtp` configuration in the provider (see Configuration section above).

## Error Handling

The MoonKey SDK automatically handles common errors in the authentication flow:

* **Invalid or expired codes** - Shows an error message and allows the user to request a new code
* **Rate limiting** - Prevents too many code requests in a short time period
* **Invalid email format** - Validates email addresses before sending codes
* **Network errors** - Displays appropriate error messages for connectivity issues

You can customize error messages using the `emailOtp` configuration options like `verifiedNewUserMessage`, `verifiedExistingUserMessage`, and `verifiedSuccessMessage`.

## Testing

### Test with different email providers

Test your email authentication flow with various email providers:

* Gmail
* Outlook/Hotmail
* Yahoo
* Corporate email domains
* Custom domains

### Test edge cases

* Invalid email format
* Non-existent email addresses
* Expired codes
* Already used codes
* Multiple login attempts

## Troubleshooting

### Emails not being received

1. Check spam/junk folders
2. Verify email domain is not blocked
3. Check email template configuration in dashboard
4. Verify DKIM and SPF records (for custom domains)

### Code verification fails

1. Ensure code hasn't expired (10-minute window)
2. Check for typos in the code
3. Verify the email address matches
4. Check that the code hasn't been used already

### Session not created

1. Verify `session_expires_in` is within valid range (5 minutes to 366 days)
2. Check API key has correct permissions
3. Ensure backend is properly handling the response
