---
title: "Catch throwaway emails with one API call"
url: "https://lookvalid.com/blog/tutorial/disposable-email-detection-api-tutorial.md"
canonical_url: "https://lookvalid.com/blog/tutorial/disposable-email-detection-api-tutorial"
last_updated: "2026-10-22"
type: "how-to"
summary: "Flag disposable email domains at signup with a short Node.js function, and learn exactly what the check reads and what it cannot see."
related: ["https://lookvalid.com/products/email-domain-check.md", "https://lookvalid.com/tools/email-domain-checker.md", "https://lookvalid.com/docs/quickstart.md", "https://lookvalid.com/glossary/disposable-email.md"]
---

# Catch throwaway emails with one API call

Flag disposable email domains at signup with a short Node.js function, and learn exactly what the check reads and what it cannot see.

Throwaway addresses almost always come from a small set of domains, so you can catch most of them by looking at the part after the @. This tutorial shows what the LookValid email domain check reads, which fields to act on, and a Node.js function you can drop into a signup handler.

## Why check the domain, not the mailbox

A disposable address service hands out inboxes on its own domains, so the domain tells you more than the local part. Checking it needs no contact with anyone: it is a DNS read and a list match.

Our check never opens a connection to the mail server, so it cannot say whether a particular mailbox exists. The response states this with `smtp_checked: false` on every result.

## What the check really does

The `disposable` field is true when the domain, or any parent domain, appears on the open disposable-email-domains list. That list is released under CC0 and maintained by contributors who add domains by pull request [1]. Matching parents means a subdomain of a listed domain is flagged too.

The list's own maintainers say they cannot guarantee that every entry is still disposable, only that basic checking was done so each was disposable at some point [1]. Plan for the occasional false positive: send a flagged signup to a softer path rather than a hard block when the cost of a lost customer is high.

The same call reads the domain's public DNS. It reports MX records, the SPF and DMARC policies, whether the domain is a free mailbox provider, and whether the local part is a role name such as info or support. A domain that publishes a null MX record is declaring that it accepts no mail at all [2], and the response marks it `null_mx` and `undeliverable`.

## The fields to use

Response fields used in the signup check

| Field | Type | What it tells you |
| --- | --- | --- |
| found | boolean | False when the domain does not exist in DNS; a free answer with a `reason` |
| data.disposable | boolean | The domain or a parent is on the open disposable list |
| data.deliverability_signal | string | good, risky or undeliverable |
| data.deliverability_reasons | array | Codes such as disposable_domain, null_mx, role_account |
| data.role_account | boolean or null | True for shared mailboxes like info@; null when you sent only a domain |
| data.free_provider | boolean | A free mailbox provider; reported, but it does not lower the signal |
| data.smtp_checked | boolean | Always false: the mail server is not contacted |

## A signup check in Node.js

The function below uses the global `fetch` built into current Node versions and returns a verdict you can act on. It treats a network failure as an error you handle yourself, rather than silently letting the signup through.

Check one address from a Node.js signup handler

```js
const API = 'https://YOUR_API_HOST';

export async function checkSignupEmail(email) {
  const res = await fetch(API + '/v1/email-domain-check', {
    method: 'POST',
    headers: {
      Authorization: 'Bearer ' + process.env.LOOKVALID_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ email }),
  });
  const body = await res.json();
  if (!res.ok) throw new Error(body.error.code + ': ' + body.error.message);
  if (!body.found) return { allow: false, why: body.reason };
  const d = body.data;
  if (d.disposable) return { allow: false, why: 'disposable domain' };
  if (d.deliverability_signal === 'undeliverable') return { allow: false, why: 'domain accepts no mail' };
  return { allow: true, review: d.deliverability_signal === 'risky' };
}

console.log(await checkSignupEmail('new.user@example.org'));
```

The last line is a sample call (top-level await needs an ES module). Each found result costs 1 credit, and a domain that does not exist comes back as a free `found: false`.

## Deciding what to do with the answer

- Block on `disposable` only where a throwaway account does real damage, such as free trials with a cost to you.
- Allow and flag when the signal is `risky` for another reason, for example a role mailbox.
- Never treat `good` as proof that a person exists. It means the domain is set up to receive mail.
- Cache your own verdicts for a domain for a few days; the API also serves a repeated lookup from its own cache for free.

For the full response and every reason code, see the [email domain check product page](https://lookvalid.com/products/email-domain-check.md), or try a domain in the [email domain checker](https://lookvalid.com/tools/email-domain-checker.md). New to the API? Start with the [quickstart](https://lookvalid.com/docs/quickstart.md).

## Sources

1. [disposable-email-domains: community list README](https://github.com/disposable-email-domains/disposable-email-domains), read 2026-10-19
2. [RFC 7505: A "Null MX" No Service Resource Record for Domains That Accept No Mail](https://www.rfc-editor.org/rfc/rfc7505.html), read 2026-10-19

By LookValid engineering. Published 2026-10-19, updated 2026-10-19.

## Related

- [Email Domain Check API](https://lookvalid.com/products/email-domain-check.md)
- [Free email domain checker (MX, SPF, DMARC)](https://lookvalid.com/tools/email-domain-checker.md)
- [Quickstart](https://lookvalid.com/docs/quickstart.md)
- [What is Disposable email?](https://lookvalid.com/glossary/disposable-email.md)
