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

@pyzit/tempmail

v0.1.1

Published

Official JavaScript/TypeScript SDK for the Pyzit disposable email detector API

Downloads

283

Readme

██████╗ ██╗   ██╗███████╗██╗████████╗
██╔══██╗╚██╗ ██╔╝╚══███╔╝██║╚══██╔══╝
██████╔╝ ╚████╔╝   ███╔╝ ██║   ██║
██╔═══╝   ╚██╔╝   ███╔╝  ██║   ██║
██║        ██║   ███████╗██║   ██║
╚═╝        ╚═╝   ╚══════╝╚═╝   ╚═╝

████████╗███████╗███╗   ███╗██████╗ ███╗   ███╗ █████╗ ██╗██╗
╚══██╔══╝██╔════╝████╗ ████║██╔══██╗████╗ ████║██╔══██╗██║██║
   ██║   █████╗  ██╔████╔██║██████╔╝██╔████╔██║███████║██║██║
   ██║   ██╔══╝  ██║╚██╔╝██║██╔═══╝ ██║╚██╔╝██║██╔══██║██║██║
   ██║   ███████╗██║ ╚═╝ ██║██║     ██║ ╚═╝ ██║██║  ██║██║███████╗
   ╚═╝   ╚══════╝╚═╝     ╚═╝╚═╝     ╚═╝     ╚═╝╚═╝  ╚═╝╚═╝╚══════╝

The official JavaScript/TypeScript SDK for the Pyzit Disposable Email Detector API

Stop fake signups. Block throwaway addresses. Protect your platform.

NPM version License TypeScript Vitest tsup


◈ What is this?

@pyzit/tempmail is the official Node.js/JavaScript client for the Pyzit Disposable Email API — a high-performance service that detects throwaway, temporary, and fake email addresses in real time.

User submits email          SDK validates it              Your app decides
─────────────────           ─────────────────             ───────────────
[email protected]  ──────► is_disposable: true  ──────►  ✗  Reject signup
[email protected]  ──────► is_disposable: false ──────►  ✓  Allow signup

Works with Next.js, Express, Nuxt, Remix, Hono, Bun, Cloudflare Workers, and any modern JS environment.


◈ Table of contents


◈ Installation

npm install @pyzit/tempmail

Or using your preferred package manager:

yarn add @pyzit/tempmail
pnpm add @pyzit/tempmail
bun add @pyzit/tempmail

Requirements: Node.js 18+ or any environment with fetch support.


◈ Quick start

import { TempMailClient } from "@pyzit/tempmail";

const client = new TempMailClient("YOUR_API_TOKEN");

const result = await client.check("[email protected]");

if (result.is_disposable) {
  console.log("❌ Disposable email — rejected");
} else {
  console.log("✅ Looks clean — allowed");
}

Get your API token at temp-mail-detector.pyzit.com.

Tip: Store your token in an environment variable, never hard-code it.

const client = new TempMailClient(process.env.PYZIT_TOKEN);

◈ API tiers

Three endpoints, three plan levels. Use only what you need.

┌─────────────────────────────────────────────────────────────────────┐
│                         ENDPOINT OVERVIEW                           │
├──────────────────┬─────────────┬──────────────────────────────────┤
│  Method          │  Plan       │  What you get                    │
├──────────────────┼─────────────┼──────────────────────────────────┤
│  client.check()  │  Free       │  is_disposable + status          │
│  client.detailed()│  Pro       │  DNS, signals, risk score, reco  │
│  client.bulk()   │  Business   │  Up to 100 emails, one request   │
└──────────────────┴─────────────┴──────────────────────────────────┘

◈ All methods

CheckResultawait client.check(email)

The fastest check. One email in, one decision out. Free tier.

const result = await client.check("[email protected]");

result.email          // "[email protected]"
result.is_disposable  // true
result.status         // "disposable"
result.is_clean       // false (convenience getter, opposite of is_disposable)

Response shape:

class CheckResult {
  email: string;
  is_disposable: boolean;
  status: "clean" | "disposable";
  readonly is_clean: boolean; // getter
}

DetailedResultawait client.detailed(email)

Full forensic analysis. DNS records, SMTP probing, reputation scoring, domain age, signal breakdown. Pro tier.

const result = await client.detailed("[email protected]");

result.risk_level       // "high"
result.recommendation   // "reject"
result.reputation_score // 0.0
result.should_reject    // true (convenience getter)

// DNS intelligence
const dns = result.details.dns_intelligence;
dns.has_mx       // false
dns.mx_hostnames() // []
dns.mx_ips()       // []

// Signal breakdown
result.details.signals.negative // ["no_mx_records", "new_domain", ...]

// Domain stability
result.details.stability.domain_age_days // 0
result.details.stability.is_new_domain   // true

Response shape:

class DetailedResult {
  email: string;
  domain: string;
  is_disposable: boolean;
  status: string;
  reputation_score: number;
  risk_level: "low" | "medium" | "high";
  recommendation: "accept" | "review" | "reject";
  readonly should_reject: boolean;
  details: {
    reputation: ReputationDetail;
    signals: Signals;
    dns_intelligence: DnsIntelligence; // has .mx_hostnames() and .mx_ips()
    stability: StabilityInfo;
  };
}

BulkResultawait client.bulk(emails)

Validate up to 100 emails in a single API call. Business tier.

const result = await client.bulk([
  "[email protected]",
  "[email protected]",
  "[email protected]",
]);

result.processed          // 3
result.results            // {"[email protected]": false, "[email protected]": true, ...}

result.disposable_emails() // ["[email protected]", "[email protected]"]
result.clean_emails()      // ["[email protected]"]

Response shape:

class BulkResult {
  results: Record<string, boolean>; // { email: isDisposable }
  processed: number;
  disposable_emails(): string[];
  clean_emails(): string[];
}

◈ Response models

The SDK uses classes for response models to provide helper methods and getters, similar to the Python version.

import { 
  CheckResult, 
  DetailedResult, 
  BulkResult 
} from "@pyzit/tempmail";

◈ Error handling

All SDK errors inherit from PyzitError, so you can catch everything at one level or be specific.

PyzitError                    ← catch-all for any SDK error
├── AuthenticationError       ← HTTP 401 — bad or missing token
├── PlanRequiredError         ← HTTP 402/403 — need a higher plan
│   └── .requiredPlan         ← string, e.g. "pro" or "business"
├── ScopeError                ← HTTP 403 — missing required scope
│   └── .requiredScope        ← string, e.g. "detailed:tempemail_check"
├── RateLimitError            ← HTTP 429 — slow down
│   └── .retryAfter           ← number, seconds to wait
├── APIError                  ← any other non-2xx response
│   ├── .statusCode           ← number
│   └── .responseBody         ← string, raw body for debugging
└── TimeoutError              ← request took too long

Recommended pattern — catch specific errors:

import { 
  TempMailClient, 
  AuthenticationError, 
  PlanRequiredError, 
  PyzitError 
} from "@pyzit/tempmail";

const client = new TempMailClient("YOUR_TOKEN");

try {
  const result = await client.check("[email protected]");
} catch (err) {
  if (err instanceof AuthenticationError) {
    console.error("Check your API token.");
  } else if (err instanceof PlanRequiredError) {
    console.error(`Upgrade to ${err.requiredPlan} plan.`);
  } else if (err instanceof PyzitError) {
    console.error("SDK Error:", err.message);
  }
}

Minimal pattern — fail open gracefully:

async function isAllowed(email) {
  try {
    const res = await client.check(email);
    return res.is_clean;
  } catch (err) {
    return true; // fail open — don't block users if API is down
  }
}

◈ Framework integrations

Next.js (App Router)

// app/api/register/route.ts
import { TempMailClient, PyzitError } from "@pyzit/tempmail";
import { NextResponse } from "next/server";

const client = new TempMailClient(process.env.PYZIT_TOKEN!);

export async function POST(req: Request) {
  const { email } = await req.json();
  try {
    const res = await client.check(email);
    if (!res.is_clean) {
      return NextResponse.json({ error: "Disposable emails blocked." }, { status: 422 });
    }
  } catch (err) {
    // fail open on API errors
    if (!(err instanceof PyzitError)) throw err;
  }
  return NextResponse.json({ ok: true });
}

Express

// middleware/validateEmail.js
import { TempMailClient } from "@pyzit/tempmail";

const client = new TempMailClient(process.env.PYZIT_TOKEN);

export async function validateEmail(req, res, next) {
  try {
    const result = await client.check(req.body.email);
    if (result.is_disposable) {
      return res.status(422).json({ error: "Temporary emails not allowed." });
    }
    next();
  } catch (err) {
    next(); // fail open
  }
}

Cloudflare Workers

import { TempMailClient } from "@pyzit/tempmail";

export default {
  async fetch(request, env) {
    const client = new TempMailClient(env.PYZIT_TOKEN);
    const { email } = await request.json();
    const result = await client.check(email);
    return Response.json({ is_disposable: result.is_disposable });
  }
};

◈ Configuration

TempMailClient accepts an options object:

const client = new TempMailClient({
  apiToken: "YOUR_TOKEN", // required
  timeout: 10000,         // milliseconds, default 10000
  baseUrl: "https://api-tempmail.pyzit.com/v1", // override for testing
});

| Parameter | Type | Default | Description | |------------|----------|--------------------------------------|------------------------------------| | apiToken | string | — | Your Pyzit API token (required) | | timeout | number | 10000 | Request timeout in milliseconds | | baseUrl | string | https://api-tempmail.pyzit.com/v1 | Override for local testing / mocks |


◈ Development

This project uses tsup for bundling and vitest for testing.

# install
npm install

# build (outputs to dist/)
npm run build

# run tests (all HTTP is mocked)
npm run test

# type check
npm run typecheck

◈ Changelog

See CHANGELOG.md.


◈ License

MIT © Pyzit


Built with care by the Pyzit team · https://pyzit.com