Email Risk Scoring: How to Automatically Block Bad Signups
Not every bad email is obviously bad — some are valid addresses attached to high-risk patterns. Risk scoring is how you catch the ones that slip past every other filter.
MailSentry Team
Email validation experts
TL;DR
- •Risk scoring replaces binary valid/invalid with a nuanced 0–1 signal
- •Use tiered decisions: accept, review, challenge, or reject based on thresholds
- •Combine email risk with IP reputation and device fingerprinting for best results
0 – 0.2
0.2 – 0.5
0.5 – 0.8
0.8 – 1.0
Binary email validation — valid or invalid — leaves a lot of nuance on the table. An address can be technically valid yet still represent a high risk to your platform. It might belong to a serial free-trial abuser, sit on a domain associated with fraud, or exhibit a pattern that strongly correlates with fake signups. Email risk scoring fills this gap by assigning a numerical confidence score that reflects how likely an address is to cause problems.
What Is a Risk Score?
A risk score is a composite value — typically between 0 and 1, where 0 means "no detectable risk" and 1 means "almost certainly problematic." It aggregates multiple signals into a single number that your application can use to make automated decisions: accept, flag for review, or reject.
Think of it as a credit score for email addresses. No single factor is dispositive, but the weighted combination of many factors produces a reliable signal.
Signals That Feed Into Risk Scoring
A robust risk-scoring model draws on a variety of inputs:
- Domain age — Newly registered domains (less than 30 days) are disproportionately associated with spam and fraud.
- Domain type — Free providers (Gmail, Yahoo) carry moderate risk. Corporate domains carry lower risk. Disposable providers carry very high risk.
- Disposable email detection — If the domain is a known disposable provider, the risk score spikes.
- Role-based prefix — Addresses like
info@andadmin@are flagged because they rarely represent individual users. - MX record health — Missing, misconfigured, or suspicious MX records increase the score.
- SMTP verification result — Mailbox does not exist, or the server is a catch-all? That is a signal.
- Pattern analysis — Randomly generated local parts (
xkq93mdf@) or local parts that match known bot patterns contribute to the score. - Historical abuse data — Has this domain or address appeared in spam traps, blacklists, or previous fraud incidents?
- DNS configuration — Does the domain have SPF, DKIM, and DMARC records? Legitimate sending domains almost always do.
How to Use Risk Scores in Your Application
The most effective pattern is a tiered decision framework with configurable thresholds:
type SignupDecision = "accept" | "review" | "challenge" | "reject";
function evaluateSignup(riskScore: number): SignupDecision {
if (riskScore <= 0.2) return "accept"; // low risk — proceed
if (riskScore <= 0.5) return "review"; // moderate — flag for manual review
if (riskScore <= 0.8) return "challenge"; // high — require CAPTCHA or phone verification
return "reject"; // very high — block signup
}Solve this with MailSentry
8 validation layers, real-time results, sub-50ms response.
Try MailSentry Free →This gives you granularity that a binary valid/invalid check cannot provide. A score of 0.4 might represent a free email provider with a slightly unusual domain — not definitively bad, but worth a second look. A score of 0.9 almost certainly indicates a disposable address on a freshly registered domain with no legitimate DNS infrastructure.
Implementing Risk-Based Signup Flow
Here is a more complete example showing how to integrate risk scoring into a registration endpoint:
// app/api/signup/route.ts
import { NextResponse } from "next/server";
export async function POST(request: Request) {
const { email, password, name } = await request.json();
// Validate email via MailSentry
const validation = await fetch(
"https://api.mailsentry.net/v1/validate",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.MAILSENTRY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ email }),
}
).then((r) => r.json());
// Hard reject: invalid email
if (!validation.is_valid) {
return NextResponse.json(
{ error: "Please provide a valid email address." },
{ status: 422 }
);
}
const riskScore = validation.risk_score;
// Tier 1: Low risk — create account immediately
if (riskScore <= 0.2) {
const user = await createUser({ email, password, name, tier: "trusted" });
await sendWelcomeEmail(user);
return NextResponse.json({ success: true, user_id: user.id });
}
// Tier 2: Moderate risk — create account but require email verification
if (riskScore <= 0.5) {
const user = await createUser({ email, password, name, tier: "unverified" });
await sendVerificationEmail(user);
return NextResponse.json({
success: true,
user_id: user.id,
requires_verification: true,
});
}
// Tier 3: High risk — require additional verification
if (riskScore <= 0.8) {
return NextResponse.json({
success: false,
challenge_required: true,
challenge_type: "captcha", // or "phone_verification"
});
}
// Tier 4: Very high risk — reject
return NextResponse.json(
{ error: "Unable to create an account with this email address." },
{ status: 422 }
);
}
Tuning Your Thresholds
The right thresholds depend on your product's risk tolerance:
- Consumer apps with free tiers tend to be more aggressive (lower reject thresholds) because free-trial abuse is expensive.
- B2B SaaS can afford to be more permissive because the signup volume is lower and manual review is feasible.
- E-commerce should be strict for account creation but permissive for guest checkout, where the downside of a bad email is limited to a lost order confirmation.
Start with conservative thresholds and adjust based on data. Log every signup decision — the email, the risk score, and the outcome — so you can review false positives and false negatives and refine your cutoffs over time.
Combining Risk Scores with Other Signals
Email risk scoring is most powerful when combined with other fraud signals:
function computeCompositeFraudScore(signals: {
emailRiskScore: number;
ipReputationScore: number;
deviceFingerprintScore: number;
velocityScore: number; // signups per hour from this IP
}): number {
return (
signals.emailRiskScore * 0.4 +
signals.ipReputationScore * 0.25 +
signals.deviceFingerprintScore * 0.2 +
signals.velocityScore * 0.15
);
}
Weighting email risk at 40 percent reflects its high signal value, but blending it with IP reputation, device fingerprinting, and velocity checks produces a more robust fraud detection system than any single signal alone.
Key Takeaways
Email risk scoring replaces binary validation with a nuanced, actionable signal that lets you automate signup decisions at scale. Feed it into a tiered decision framework — accept, review, challenge, reject — and tune your thresholds based on your product's risk profile. Combine it with other fraud signals for defense in depth, and log everything so you can iterate. The result is a signup flow that blocks the vast majority of bad actors while minimizing friction for legitimate users.
Try MailSentry Free
8 validation layers, sub-50ms response, 1,000 checks/month free.
Get Your Free API Key →