MailOdds
Tutorials 10 min read January 14, 2026

Email Validation API for JavaScript: Real-Time Signup Protection

Learn how to integrate email validation into JavaScript applications. Covers React form validation, vanilla JS, and Node.js with the MailOdds TypeScript SDK.

Invalid email signups cost businesses money and damage deliverability. Every hard bounce chips away at your sender reputation, pushing legitimate emails into the spam folder. According to data published by HubSpot, the average email list decays by 22.5% annually, making real-time validation at the point of entry a technical necessity rather than a nice-to-have.

Most JavaScript developers start with a regex pattern in their signup form and call it a day. The problem: regex can only check whether a string looks like an email address. It cannot tell you whether the mailbox actually exists, whether the domain is a disposable email provider, or whether the server is a catch-all that accepts everything. API-based validation solves all of these problems by checking the actual mail server in real time.

This guide walks through three integration patterns: vanilla JavaScript for static sites, React with TypeScript for modern SPAs, and server-side Node.js for API routes. Each example is production-ready and follows the fail-open principle so your signup flow never breaks.

Why Not Just Use Regex?

The email address format defined in RFC 5322 is notoriously complex. According to RFC 5322 Section 3.4, valid email addresses can include quoted strings, comments, and domain literals, making comprehensive regex validation practically impossible. A regex pattern that correctly handles every valid address would span thousands of characters and still miss edge cases.

Beyond format, regex cannot answer the questions that actually matter for deliverability:

  • Does the mailbox actually exist on the receiving server?
  • Is the domain a disposable email provider like Mailinator or Guerrilla Mail?
  • Is the server configured as catch-all, accepting mail for any address regardless of whether it exists?
  • Is the address a role account (info@, support@) that typically has lower engagement?

An API-based validator performs syntax checks, DNS lookups, and SMTP mailbox verification in a single call, returning a structured response you can act on. For more on the five levels of validation, see the email validation rules guide.

Step 1: Install the MailOdds TypeScript SDK

The MailOdds TypeScript SDK works in Node.js, Deno, and browser environments. Install it from npm:

Terminal
npm install mailodds

Configure the client with your API key:

typescript
import { MailOdds } from 'mailodds';

const client = new MailOdds({
  apiKey: process.env.MAILODDS_API_KEY,
  baseUrl: 'https://api.mailodds.com'
});

Get your API key from the dashboard. The free tier includes 50 validations per month with no credit card required.

Step 2: Vanilla JavaScript Form Validation

For static sites, marketing landing pages, or any project without a framework, you can call the MailOdds API directly from a form submit handler. This example validates the email before allowing the form to proceed.

html
<form id="signup-form">
  <input type="email" id="email" placeholder="you@company.com" />
  <span id="email-status"></span>
  <button type="submit">Sign Up</button>
</form>
javascript
const form = document.getElementById('signup-form');
const emailInput = document.getElementById('email');
const status = document.getElementById('email-status');

form.addEventListener('submit', async (e) => {
  e.preventDefault();
  const email = emailInput.value.trim();

  status.textContent = 'Validating...';

  try {
    const response = await fetch('https://api.mailodds.com/v1/validate', {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ email })
    });

    const result = await response.json();

    if (result.action === 'reject') {
      status.textContent = 'This email appears to be invalid.';
      status.style.color = 'red';
    } else if (result.action === 'flag') {
      status.textContent = 'This email may have issues. Please verify.';
      status.style.color = 'orange';
    } else {
      status.textContent = 'Email verified!';
      status.style.color = 'green';
      form.submit();
    }
  } catch (error) {
    // Fail open: allow signup if validation service is unreachable
    form.submit();
  }
});

Fail-open pattern

If the validation API is unreachable due to a network issue or timeout, the catch block allows the signup to proceed. This ensures your registration flow never breaks, even during an outage. You can clean invalid addresses later with bulk validation.

Step 3: React Form Validation with TypeScript

In React applications, you can wrap the validation logic in a component with state management. This example uses the MailOdds TypeScript SDK and highlights the did_you_mean field, which suggests corrections for common typos like "gmial.com" or "yaho.com".

tsx
import { useState } from 'react';
import { MailOdds } from 'mailodds';

const client = new MailOdds({
  apiKey: process.env.NEXT_PUBLIC_MAILODDS_KEY!,
  baseUrl: 'https://api.mailodds.com'
});

interface ValidationResult {
  status: string;
  action: string;
  sub_status: string;
  did_you_mean: string | null;
}

export function SignupForm() {
  const [email, setEmail] = useState('');
  const [validating, setValidating] = useState(false);
  const [result, setResult] = useState<ValidationResult | null>(null);

  const handleValidate = async () => {
    if (!email) return;
    setValidating(true);

    try {
      const res = await client.validate({ email });
      setResult(res);
    } catch {
      // Fail open
      setResult({ status: 'unknown', action: 'accept',
        sub_status: '', did_you_mean: null });
    } finally {
      setValidating(false);
    }
  };

  return (
    <form onSubmit={(e) => { e.preventDefault(); handleValidate(); }}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="you@company.com"
      />
      {result?.did_you_mean && (
        <p>Did you mean {result.did_you_mean}?
          <button type="button"
            onClick={() => setEmail(result.did_you_mean!)}>
            Use suggestion
          </button>
        </p>
      )}
      {result?.action === 'reject' && (
        <p style={{ color: 'red' }}>
          Invalid email: {result.sub_status.replace(/_/g, ' ')}
        </p>
      )}
      <button type="submit" disabled={validating}>
        {validating ? 'Validating...' : 'Sign Up'}
      </button>
    </form>
  );
}

The did_you_mean field is one of the most impactful features for signup conversion. When a user types "jane@gmial.com", the API returns a suggestion of "jane@gmail.com". Displaying this suggestion inline prevents a valid user from being blocked by a simple typo, and reduces support tickets from users who never received their confirmation email.

Step 4: Server-Side Validation with Node.js

For production applications, server-side validation is the recommended approach. Your API key stays on the server and is never exposed to the browser. This is especially important if you want to block disposable email addresses, since a determined user could bypass client-side checks.

typescript
import express from 'express';
import { MailOdds } from 'mailodds';

const app = express();
const client = new MailOdds({
  apiKey: process.env.MAILODDS_API_KEY!,
  baseUrl: 'https://api.mailodds.com'
});

app.post('/api/signup', async (req, res) => {
  const { email, name } = req.body;

  // Server-side validation (API key stays secret)
  const validation = await client.validate({ email });

  if (validation.action === 'reject') {
    return res.status(400).json({
      error: 'Invalid email address',
      reason: validation.sub_status
    });
  }

  if (validation.disposable) {
    return res.status(400).json({
      error: 'Disposable email addresses are not allowed'
    });
  }

  // Proceed with user registration
  // ...

  res.json({ success: true });
});

This pattern works with any Node.js framework: Express, Fastify, Next.js API routes, or Hono. The key principle is the same: validate on the server, reject before writing to your database. See the full TypeScript SDK documentation for additional methods including bulk validation and webhook setup.

Handling Edge Cases

Production email validation involves several edge cases that are easy to overlook during initial integration. Here are the most common scenarios and how to handle them:

Catch-all domains

Some mail servers accept mail for any address at their domain, making it impossible to confirm whether a specific mailbox exists. The API returns a catch_all status for these. Treat them as a flag rather than a hard reject, since many legitimate business domains use catch-all configurations.

Rate limiting

MailOdds returns a 429 status code with a Retry-After header when you exceed your plan's rate limit. The TypeScript SDK handles retries automatically. If you are calling the API directly, read the header value and wait before retrying.

Timeouts

Set a reasonable timeout of 5 seconds for validation requests. If the request times out, follow the fail-open pattern: allow the signup and validate the address asynchronously later. A slow SMTP server should not block your user from completing registration.

Disposable emails

Whether to block disposable email addresses depends on your use case. SaaS signup forms typically block them to prevent abuse. Newsletter signups may accept them since the cost of a disposable subscriber is low. The disposable boolean in the response gives you the flexibility to decide.

Google and Yahoo Sender Requirements

According to Google's 2024 Bulk Sender Guidelines and Yahoo's corresponding requirements, senders processing more than 5,000 emails per day must maintain bounce rates below 0.3% and implement one-click unsubscribe. Violating these thresholds results in throttling or outright blocking of your sending domain.

Validating email addresses before they enter your system is the most effective way to meet these requirements. A single validation call at signup prevents hard bounces from ever reaching your sending infrastructure. Combined with proper authentication (SPF, DKIM, DMARC), real-time validation forms the foundation of a healthy sender reputation.

For a deeper look at building and maintaining sender reputation, see the email deliverability guide.

Start validating emails in JavaScript

Install the MailOdds TypeScript SDK and validate your first email in under 2 minutes. 50 free validations per month, no credit card required.