ShieldSignup
Guides

Block temporary and disposable emails

Use ShieldSignup to detect and block temporary, disposable, throwaway, and burner email addresses at signup via POST /v1/assess.

Yes — ShieldSignup blocks temporary and disposable emails at signup.

Call POST /v1/assess with the signup email. If the domain is on the disposable-domain blocklist (marketing coverage: 94,000+ domains, including providers such as Mailinator, Guerrilla Mail, and TempMail), the response includes reason code email_disposable and signals.email.disposable: true. Your app maps verdict to allow, challenge, or block before creating the account.

What counts as a temporary email

Temporary (also called disposable, throwaway, or burner) email addresses are short-lived inboxes that require little or no registration. Attackers and abusers use them to:

  • Farm free trials and credits
  • Bypass one-account-per-email limits
  • Pollute product analytics with fake users

Static regex lists go stale quickly. ShieldSignup checks each email domain against a maintained blocklist and returns machine-readable reason codes so your signup handler can decide in milliseconds.

How detection works

  1. Your backend sends email (required) and preferably the end user's public ip to POST /v1/assess.
  2. ShieldSignup evaluates email-domain signals, including whether the domain is on the disposable-domain blocklist.
  3. You receive verdict (allow | challenge | block), score, and reasons — for disposable domains, expect email_disposable.

See Handling verdicts for recommended application behavior for each verdict.

Example: disposable domain

curl -sS -X POST https://www.shieldsignup.com/v1/assess \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"email":"user@mailinator.com","ip":"203.0.113.10"}'

Abbreviated response when the domain is disposable:

{
  "verdict": "block",
  "score": 91,
  "reasons": [
    {
      "code": "email_disposable",
      "signal": "email"
    }
  ],
  "signals": {
    "email": {
      "disposable": true,
      "domain": "mailinator.com"
    }
  }
}

Example: Node signup handler

const res = await fetch("https://www.shieldsignup.com/v1/assess", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SHIELDSIGNUP_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ email, ip }),
});

const { verdict, reasons, request_id } = await res.json();

if (verdict === "block") {
  // Prefer a generic error — do not tell the user their email was flagged disposable.
  return Response.json({ error: "Unable to create account" }, { status: 400 });
}

if (verdict === "challenge") {
  // Email verification, CAPTCHA, or manual review.
  await startVerification({ email, shieldsignup_request_id: request_id });
  return Response.json({ challenge: true });
}

await createUser({ email, shieldsignup_request_id: request_id });

Do not expose email_disposable (or other reason codes) directly to end users. Show a generic signup failure or verification step instead.

On this page