npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@emailsherlock/node

v0.2.0

Published

Official Node.js client for the EmailSherlock email-verification API.

Readme

@emailsherlock/node

Official Node.js client for the EmailSherlock email-verification API. Verify one address or a batch over HTTPS with an API key. Get an API key at https://emailsherlock.com/api. Want to try a single address by hand first? The free email verification tool runs the same checks in the browser.

Zero dependencies. Works on Node 18+ (uses the built-in fetch).

Install

npm install @emailsherlock/node

Quick start

import { Emailsherlock } from '@emailsherlock/node';

// reads the key from the environment, never hard-code it
const es = new Emailsherlock(process.env.ES_KEY);

const result = await es.verify.single({ email: '[email protected]' });

console.log(result.result); // 'valid'
console.log(result.score);  // 0.95

The constructor also reads ES_KEY (or EMAILSHERLOCK_API_KEY) from the environment if you call new Emailsherlock() with no argument.

Batch

Up to 100 addresses per call:

const { results } = await es.verify.batch({
  emails: ['[email protected]', '[email protected]'],
});

results[0].result; // 'valid'
results[1].role;   // true

A batch item is either a result object or a per-address error. Narrow it with the type guard:

import { isVerifyResult } from '@emailsherlock/node';

for (const item of results) {
  if (isVerifyResult(item)) {
    console.log(item.email, item.result);
  } else {
    console.log(item.email, 'failed:', item.error);
  }
}

The result object

| field | type | meaning | |--------------|-----------|-----------------------------------------------------------------| | email | string | the address you sent | | result | string | valid · invalid · catch_all · disposable · role · unknown | | mx | boolean | the domain has reachable MX records | | disposable | boolean | throwaway / temporary-mail provider | | role | boolean | role address such as info@ or sales@ | | catch_all | boolean | host accepts mail for any local part | | score | number / null | 0–1 confidence, higher is safer to send to (null when the verdict is unknown) | | freshness | string | fresh · cached_recent · cached_stale_refreshed | | deliverable| boolean / null | SMTP-proven: true only after an SMTP accept, false only on a provable failure, null when unproven | | reason | string / null | why the verdict came out the way it did, e.g. mailbox_accepts · mailbox_not_found · no_mx · bad_syntax · disposable_provider · role_address · catch_all_domain · greylisted · smtp_timeout · smtp_unreachable · verification_pending | | mx_record | string / null | the primary MX host for the domain | | free_email | boolean / null | the address belongs to a free webmail provider | | checked_at | string / null | when the check ran, ISO 8601 | | domain | object / null | domain-level intelligence, see below |

The fields from deliverable down are additive and may be missing until the API rollout completes; once present they are always set but nullable.

The domain object

| field | type | meaning | |----------------|-----------|----------------------------------------------------------| | name | string | the domain part of the address | | types | string[] / null | host types: freemail · disposable · custom · company · government · education · public · isp | | score | number / null | domain trust score, 0-100, higher is better | | spf | boolean / null | the domain publishes an SPF record | | dkim | boolean / null | the domain publishes at least one DKIM key | | dmarc | boolean / null | the domain publishes a DMARC record | | dmarc_policy | string / null | none · quarantine · reject | | mta_sts | boolean / null | the domain publishes an MTA-STS policy | | tls_rpt | boolean / null | the domain publishes a TLS-RPT record | | bimi | boolean / null | the domain publishes a BIMI record | | dane | boolean / null | the MX hosts publish DANE/TLSA records | | blacklists | number / null | DNS blacklists currently listing the domain's mail IPs | | dnssec | string / null | secure · insecure · bogus | | caa | boolean / null | the domain publishes a CAA record |

Credits and rate limits

After every call the client exposes what the response headers reported:

es.creditsRemaining;   // e.g. 41
es.rateLimit;          // { limit, remaining, reset }

Errors

Every failure throws a subclass of EmailsherlockError:

| class | HTTP | when | |-----------------------------|------|-----------------------------------------------| | AuthenticationError | 401 | missing or invalid API key | | ForbiddenError | 403 | key lacks the endpoint's scope (requiredScope) | | InsufficientCreditsError | 402 | not enough credits (creditsRequired, creditsRemaining) | | RateLimitError | 429 | rate limit hit (retryAfter, limit, remaining, reset) | | ValidationError | 400 / 422 | the request body was rejected | | ServiceUnavailableError | 503 | verify engine unavailable (the credit is auto-refunded) |

import { RateLimitError } from '@emailsherlock/node';

try {
  await es.verify.single({ email: '[email protected]' });
} catch (err) {
  if (err instanceof RateLimitError) {
    console.log(`retry after ${err.retryAfter}s`);
  } else {
    throw err;
  }
}

Options

new Emailsherlock({
  apiKey: process.env.ES_KEY,
  baseUrl: 'https://api.emailsherlock.com', // default
  timeoutMs: 30000,                          // default
  fetch: customFetch,                        // optional injection
});

License

MIT. Full API reference: https://emailsherlock.com/api/docs