Express · TypeScript
Block disposable email in Express
Express middleware calls Piisend on POST /signup (or your auth route) before passport or custom user creation runs.
The code
// middleware/disposableEmail.ts
import type { Request, Response, NextFunction } from "express";
const PIISEND_URL = "https://api.piisend.com/api/v1/intelligence/email";
export async function blockDisposableEmail(req: Request, res: Response, next: NextFunction) {
const email = req.body?.email;
if (!email) return next();
try {
const r = await fetch(PIISEND_URL, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PIISEND_API_KEY!}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ email }),
});
if (r.ok && (await r.json()).signals?.disposable) {
return res.status(400).json({ error: "Please use a permanent email address." });
}
} catch {
// fail open
}
next();
}
// app.ts
import express from "express";
import { blockDisposableEmail } from "./middleware/disposableEmail";
const app = express();
app.use(express.json());
app.post("/signup", blockDisposableEmail, signupHandler);API key
Use `dotenv` in development; inject `PIISEND_API_KEY` via your host's secret store in production.
Fail-open vs fail-closed
Middleware calls `next()` on errors — swap for 503 if you need fail-closed.
Pair with verification
Place middleware before passport-local or your ORM user-create handler.
Send verification email with Piisend
After blocking disposable addresses, send OTP and verification mail through the same Piisend account. One API key for intelligence checks and transactional sends.