A small middleware: check the email on the signup route, reject block, attach the verdict for allow and review, and never let our API become a single point of failure.
The middleware
// middleware/require-work-email.js
const API = 'https://api.isbusinessemail.com/v1/check';
export function requireWorkEmail({ policy = 'b2b', timeoutMs = 2500, field = 'email' } = {}) {
return async function (req, res, next) {
const email = String(req.body?.[field] ?? '').trim();
if (!email) return res.status(422).json({ field, message: 'Email is required.' });
let verdict;
try {
const r = await fetch(API, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.IBE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, policy }),
signal: AbortSignal.timeout(timeoutMs),
});
if (r.ok) {
verdict = await r.json();
} else {
req.log?.warn?.({ status: r.status }, 'isBusinessEmail error');
}
} catch (err) {
req.log?.warn?.({ err: err.name }, 'isBusinessEmail unreachable');
}
// Fail open: no verdict means allow, flagged for a later re-check.
req.emailVerdict = verdict ?? { recommendation: 'allow', failOpen: true };
if (req.emailVerdict.recommendation === 'block') {
return res.status(422).json({
field,
code: 'work_email_required',
message: 'Please use your work email.',
did_you_mean: req.emailVerdict.did_you_mean ?? null,
});
}
next();
};
}
Use it
import express from 'express';
import { requireWorkEmail } from './middleware/require-work-email.js';
const app = express();
app.use(express.json());
app.post('/signup', requireWorkEmail(), async (req, res) => {
const v = req.emailVerdict;
const user = await createUser({
email: req.body.email,
emailCategory: v.category ?? null,
needsReview: v.recommendation === 'review' || v.failOpen === true,
microsoft365: v.workspace?.microsoft_365?.detected ?? null,
googleWorkspace: v.workspace?.google_workspace?.detected ?? null,
});
res.status(201).json({ id: user.id });
});
app.listen(3000);
Notes
- Node 18+ provides
fetchandAbortSignal.timeout; no dependencies needed. 422withdid_you_meanlets your frontend show “Did you mean …?” next to the field.- Use
requireWorkEmail({ policy: 'strict' })on routes that need a company tenant, such as starting a Microsoft 365 integration. - Unit-test with test addresses, and mock
fetchfor the timeout path.
Official docs: Express. See also: Signup form guide · Code examples.