1. Home
  2. API docs
  3. Node.js

Email verification API in Node.js

To verify an email in Node.js, call https://simpleverifier.com/api/v1/verify with fetch, the address in the email query parameter and your key as a Bearer token. The JSON status is valid, risky or invalid. Use AbortSignal.timeout to cap the wait, and treat a timeout or error as unknown rather than invalid.

By SimpleVerifier Team

Before you start

  • Create a key on the API keys page. Keys start with sv_live_ and are shown once.
  • Set SIMPLEVERIFIER_KEY in the environment (or load it with node --env-file=.env on Node 20.6 and later).
  • API access is included in the Pro plan ($29.99/month) and the Email + Phone plan ($49.99/month). See pricing.

1. Add the helper

No dependencies: Node 18 and later ship fetch and AbortSignal.timeout. It never throws, so callers only have to handle four outcomes.

simpleverifier.mjs
// simpleverifier.mjs — Node.js 18+, no dependencies
const API_URL = "https://simpleverifier.com/api/v1/verify";
const EMAIL_SHAPE = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;

/**
 * Resolves to "valid", "risky" or "invalid", or null when the API could not
 * answer (timeout, rate limit, outage). Never throws.
 */
export async function emailStatus(email) {
  const address = String(email ?? "").trim();
  if (!EMAIL_SHAPE.test(address)) return "invalid"; // no API call made

  try {
    const res = await fetch(`${API_URL}?email=${encodeURIComponent(address)}`, {
      headers: { Authorization: `Bearer ${process.env.SIMPLEVERIFIER_KEY}` },
      signal: AbortSignal.timeout(30_000),
    });
    if (!res.ok) {
      console.warn(`SimpleVerifier returned HTTP ${res.status}`);
      return null; // 401, 402, 429, 503: fail open
    }
    const data = await res.json();
    return data.status ?? null;
  } catch (err) {
    console.warn(`SimpleVerifier unreachable: ${err.name}`);
    return null;
  }
}

2. Act on the result

Only invalid should block a person.

example.mjs
import { emailStatus } from "./simpleverifier.mjs";

const status = await emailStatus("jane@company.com");

if (status === "invalid") {
  console.log("Rejected: this address cannot receive mail");
} else if (status === "risky") {
  console.log("Accepted, but delivery is not confirmed");
} else if (status === "valid") {
  console.log("Accepted: the mailbox exists");
} else {
  console.log("API unavailable: accepted without a mailbox check");
}

3. Check a short list

Each key can make 120 calls a minute. A sequential loop with a short pause stays under it; for large lists, upload a CSV in the dashboard instead.

bulk.mjs
import { emailStatus } from "./simpleverifier.mjs";

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

/** Checks a short list one address at a time, staying under 120 calls a minute. */
export async function verifyMany(emails) {
  const results = new Map();
  for (const email of emails) {
    results.set(email, await emailStatus(email));
    await sleep(500);
  }
  return results;
}

What the API returns

GET or POST https://simpleverifier.com/api/v1/verify with email runs the syntax, domain, disposable-domain and live mailbox checks in one call and returns:

{
  "email": "jane@company.com",
  "status": "valid",
  "reason": "Mailbox exists",
  "mailbox_checked": true
}

Every snippet above follows the same rule: only a successful response with status set to invalid blocks a person.

ResultWhat it meansWhat to do
validThe mail server confirmed the mailbox exists.Accept.
riskyThe domain is real but the mailbox couldn't be confirmed: catch-all domains, role addresses like info@, providers that hide mailbox status.Accept on signup forms. Store the status and keep these out of cold campaigns.
invalidBad format, no mail server, a disposable domain, or the mailbox doesn't exist.Reject and ask the person to check the address.
timeout, 429 or 503The check didn't finish: a slow mail server, too many calls this minute, or a brief outage.Accept (fail open) and log it. Re-check later if it matters.
401 or 402The key is wrong or revoked, or the subscription isn't active.Accept, and alert yourself: every check is being skipped until it's fixed.

Errors return JSON with an error message. Each key can make 120 calls a minute; for thousands of addresses, upload a CSV in the dashboard instead.

Phone numbers and spreadsheets

The same key works with /api/v1/phone?phone=…&country=… to validate a phone number and normalise it to E.164, with live carrier lookups on the Email + Phone plan. The request and response are in the API reference. To check a column of addresses without code, use the Google Sheets add-on with the same key.

Common questions

Is there an npm package?
You don't need one. The helper above is the whole integration in plain fetch, with nothing to install. The SDK page lists the official Node.js and Python clients and whether they are available yet.
Does this work in TypeScript?
Yes. Rename the file to .ts and type the return as Promise<"valid" | "risky" | "invalid" | null>. The Next.js guide has a typed version you can copy.
How much does the SimpleVerifier API cost?
API access is included in the paid plans: Pro at $29.99/month and Email + Phone at $49.99/month. There are no per-call credits. Each key can make 120 calls a minute.
Should I reject risky addresses?
Not on a signup or contact form. Risky means the mailbox couldn't be confirmed, which includes every address at a catch-all company domain. Accept it, store the status, and leave risky addresses out of cold outreach.
What if the API is slow or down?
Let the address through. A mailbox check can take several seconds when a mail server is slow, so cap the wait at about 30 seconds (less on a busy form) and treat a timeout, a 429 or a 503 as unknown rather than invalid.

Ready to clean your email and phone lists?

Start verifying emails and phone numbers today and boost your deliverability.

Get Started

Cancel anytime • No setup required