Email validation in JavaScript, from regex to API

Most JavaScript tutorials stop at a regex, and that's why so many forms still collect addresses that bounce. The regex catches ada@ and ada example.com. It can't catch ada@examplecorp.com when that company shut its mail server last spring.

This guide gives you working code for each layer and shows where each one runs. Your API key stays on the server the whole time. For the pattern itself and its versions in other languages, see the email validation regex guide.

The short version

  • A form you control, plus a server route or serverless function (Node.js 18 or later has fetch built in)
  • A ZapBounce API key, kept in a server environment variable

The steps

  1. Use the email input type

    Write <input type="email" name="email" required>. The browser now blocks submit on a missing at-sign and shows its own message, with no script at all. Mobile keyboards also switch to an email layout, which cuts typos before they happen.

  2. Read the browser's verdict in script

    Call input.checkValidity() to get true or false, and input.validity.typeMismatch to know the reason was the address format. Use input.setCustomValidity("...") if you want your own wording in the message.

  3. Add a short regex test

    Test the trimmed value with /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value). The browser's own rule allows a domain with no dot, like ada@localhost, and this pattern closes that gap for a public form.

  4. Send the address to your own server

    On blur, post the address to a route on your server, such as /api/check-email. Never call the verification API straight from the browser, because anyone can read a key that ships in page source.

  5. Call the verification API from the server

    In your route, call fetch("https://api.zapbounce.com/v1/verify", { method: "POST", headers: { Authorization: "Bearer " + process.env.ZAPBOUNCE_KEY, "Content-Type": "application/json" }, body: JSON.stringify({ email }) }). The Node.js page shows the same call with error handling.

  6. Set a timeout and fail open

    Wrap the call in an AbortController with a timeout, and accept the address if the timer fires. A slow mail server should never cost you a signup. Check the address again later from your backend.

  7. Act on the result

    Block invalid. Accept valid. Accept catch_all and unknown too, and tag them for a follow-up check. If did_you_mean holds a suggestion, show it next to the field so the person can fix a typo like gmial.com with one tap.

What each layer catches

The email input and the regex run in the browser and cost nothing. They catch missing at-signs, spaces and half-typed domains, which are the mistakes people make while typing fast on a phone.

The API call runs on your server and asks the real question. ZapBounce looks up the domain's MX record, opens an SMTP connection on port 25, offers the address at RCPT TO and closes before any message is sent. You get back valid, invalid, catch_all or unknown, plus role and disposable flags you can use to turn away throwaway inboxes.

Our real-time verification page covers the signup use case in more depth, including what to do with each result.

What a signup check costs

Each address costs one credit when we get an answer from a mail server. An unknown result is never billed, and neither is a request that fails on our side. Any call made with a zb_test_ sandbox key is free, so you can build and test the whole flow first.

You get 100 free checks a month with no card. After that it's $5 for 1,000 checks or $25 for 10,000, and credits never expire. The pricing page has every tier.

Questions people ask

How do I validate an email address in JavaScript?

Use an input with type email for browser feedback, test the trimmed value against a short regex such as ^[^\s@]+@[^\s@]+\.[^\s@]+$, and then check the mailbox with a server-side API call. The first two catch typos, and the API call catches addresses that do not exist.

Is HTML5 email validation enough?

HTML5 validation is enough for format only. It blocks a missing at-sign but accepts a domain with no dot, and it has no way to see whether the mailbox exists. Add a regex for the dot and a server-side check for the mailbox.

Can I call an email verification API from the browser?

Call it from your server instead. A key placed in browser code is visible to every visitor, who could spend your credits. Post the address to your own route and make the API call there.

How long does an email verification call take?

The time depends on the receiving mail server, because the check waits for its reply at RCPT TO. Greylisting and throttled servers answer slowly, so set a client timeout and accept the address when it expires.

Run your list through it

100 free checks a month, no card. Every address comes back with one verdict, and unknowns are never billed.