DEV Community

Cover image for How to Build a Fraud Detection API Check Using WHOIS Domain Data
Furqan Ashraf
Furqan Ashraf

Posted on AI-assisted

How to Build a Fraud Detection API Check Using WHOIS Domain Data

TL;DR

  • A fake business signup often hides behind a company website that looks fine but was registered days or weeks ago
  • WHOIS data exposes four checkable patterns: registration age, bulk registration bursts, reused registrant emails, and shared nameservers
  • None of these signals should block a signup on its own. Combine them into a score and use the score to decide between allow, review, or block
  • Privacy-protected WHOIS records and old-but-compromised domains are real blind spots. Treat this as one signal in a stack, not a fraud engine by itself

The Problem With Trusting a "Company Website" Field

Most B2B signup forms ask for a company name and a work email, and plenty ask for a website too, treating it as a lightweight proof the business is real. It is not much of one. Registering a domain costs less than lunch and takes under five minutes at most registrars, no ID required.

That gap is exactly what fake signups, trial abuse, and fraud rings exploit. The business name looks plausible, the email domain resolves, and the website even loads. What a human reviewer rarely checks, and what most signup validation skips entirely, is when that domain was actually registered and who else it might be connected to. A fraud detection API built on that one data point catches a surprising share of this traffic, before it ever reaches manual review.

What WHOIS Data Actually Reveals

WHOIS is the public record every domain registration creates. It was built for network administration, not fraud detection, and ICANN requires registries and registrars to make registration data available as a condition of operating. A handful of its fields turn out to be some of the most reliable low-effort fraud signals available.

Registration and Expiry Dates

Every domain has a creation date and an expiry date. A business that has operated for five years usually has a domain registered around the same time. A domain registered three days ago, attached to a company claiming years of history, is a mismatch worth flagging.

Registrant and Organization Fields

Depending on privacy settings, WHOIS can expose the registrant's name, organization, and email address. Fraud rings frequently reuse the same registrant email or a close variant across dozens of throwaway domains, because generating a fresh identity for every domain is more effort than most operators bother with.

Registrar and Nameservers

The registrar handling the domain and the nameservers it points to are both visible in most WHOIS records. Legitimate businesses tend to spread across mainstream registrars and standard hosting nameservers. Clusters of unrelated domains sharing the same obscure nameserver are a pattern worth a second look.

Four Patterns That Reveal Fake or Fraudulent Signups

Infographic showing four WHOIS patterns that reveal fake signups: domains registered right before signup, bulk registration bursts, reused registrant emails, and shared nameservers

Domains Registered Right Before Signup

This is the simplest and highest-value check. If the domain backing a signup was registered in the last 24 to 72 hours, that alone is not proof of fraud, but it is a strong enough signal to route the signup into manual review instead of instant approval, especially for high-value actions like starting a paid trial or requesting a large credit limit.

Bulk Registration Bursts

Attackers rarely register one domain and stop. A common pattern is dozens of similarly named domains registered within the same hour through the same registrar, for example acme-solutions-inc.com, acme-solutions-llc.net, and acmesolutions-corp.org all created minutes apart. Sorting recent signups by domain creation timestamp surfaces these clusters immediately.

Reused Registrant Emails Across "Different" Companies

When WHOIS privacy is off, or partially off, the registrant email is visible. Seeing the same registrant email, or an obvious pattern like ops1@, ops2@, ops3@ on the same free provider, attached to multiple domains signing up as unrelated businesses is one of the strongest correlation signals available.

Shared Nameservers Across Unrelated Domains

Legitimate small businesses usually sit on whatever nameservers their hosting provider or domain registrar assigns by default. A group of signup domains all pointing to the same obscure, unfamiliar nameserver, especially one not tied to a known hosting brand, often means they were all set up by the same operator using the same automated tooling.

Turning These Patterns Into a Risk Score

No single WHOIS signal should ever block a signup by itself. Legitimate startups launch on brand-new domains constantly, and privacy-protected WHOIS is common and completely normal. The value comes from combining signals into a score, including a neutral baseline for the very common case of privacy protection, shown in the last row below.

Signal What It Suggests False Positive Risk Suggested Action
Domain registered under 72 hours ago Possible throwaway infrastructure Medium, new businesses do this too Flag for review, do not auto-block
Domain registered 1 to 4 weeks ago Mildly suspicious in isolation High on its own Weight lightly, combine with other signals
Registrant email reused across 3+ recent signups Likely the same operator Low if the match is exact Hold for manual review
Shared nameserver across unrelated signup domains Possible shared tooling or infrastructure Medium, shared hosting is common Weight lightly unless paired with other flags
WHOIS privacy fully enabled Common and mostly neutral High if used alone Do not penalize by itself

Treat each row as a point value rather than a hard rule, add the points, and set a threshold. A domain that trips two or three of these at once is worth a human's attention. A domain that trips only "registered recently" is very often just a new business.

A Working Example: Checking Domain Age on Signup

Here is a minimal Node.js 18+ example that pulls a domain's registration date on signup and flags anything under a configurable age threshold. This uses environment variables for the API key and includes basic error handling, since a failed lookup should never block a legitimate signup outright. Tested against the live WhoisFreaks endpoint on real domains, confirmed working.

// domainAgeCheck.js
// Requires WHOIS_API_KEY set as an environment variable, never hardcode it

const WHOIS_API_KEY = process.env.WHOIS_API_KEY;
const MIN_DOMAIN_AGE_DAYS = 30; // tune this to your own risk tolerance

async function checkDomainAge(domain) {
  if (!WHOIS_API_KEY) {
    throw new Error("Missing WHOIS_API_KEY environment variable");
  }

  try {
    const response = await fetch(
      `https://api.whoisfreaks.com/v1.0/whois?apiKey=${WHOIS_API_KEY}&whois=live&domainName=${domain}`
    );

    if (!response.ok) {
      // Fail open on a lookup error, do not block a real signup over an API hiccup
      console.error(`WHOIS lookup failed for ${domain}: ${response.status}`);
      return { flagged: false, reason: "lookup_failed" };
    }

    const data = await response.json();

    // domain_registered comes back "no" for unregistered domains, with no create_date
    if (data?.domain_registered !== "yes" || !data?.create_date) {
      return { flagged: false, reason: "no_creation_date" };
    }

    const ageInDays = Math.floor(
      (Date.now() - new Date(data.create_date).getTime()) / (1000 * 60 * 60 * 24)
    );

    return {
      flagged: ageInDays < MIN_DOMAIN_AGE_DAYS,
      ageInDays,
      reason: ageInDays < MIN_DOMAIN_AGE_DAYS ? "recently_registered" : "ok",
    };
  } catch (err) {
    console.error("WHOIS check error:", err);
    return { flagged: false, reason: "error" };
  }
}

// Usage during signup
const result = await checkDomainAge("example-newcompany.com");
if (result.flagged) {
  // route to manual review, do not hard block on this alone
}
Enter fullscreen mode Exit fullscreen mode

This runs against WhoisFreaks' live WHOIS endpoint and returns create_date at the top level of the response, along with a domain_registered flag worth checking explicitly, since an unregistered domain still returns a 200 OK with domain_registered: "no" rather than an error. The code above checks for that case directly instead of relying only on a missing create_date.

What the Response Actually Looks Like

The full response includes a lot more than the age check needs, registrant contact details, raw WHOIS text, and a duplicate registry_data block. Here are the fields that actually matter for fraud detection, trimmed from a real lookup:

{
  "domain_name": "google.com",
  "domain_registered": "yes",
  "create_date": "1997-09-15",
  "update_date": "2024-08-02",
  "expiry_date": "2028-09-13",
  "domain_registrar": {
    "registrar_name": "MarkMonitor, Inc",
    "iana_id": "292"
  },
  "name_servers": [
    "ns1.google.com",
    "ns2.google.com",
    "ns3.google.com",
    "ns4.google.com"
  ],
  "domain_status": [
    "clientupdateprohibited",
    "clienttransferprohibited",
    "clientdeleteprohibited"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Here is how each field maps back to the four patterns covered earlier:

Field Feeds Into How
create_date Domain age check Core of the pattern in the code example above
domain_registrar.registrar_name Bulk registration bursts Group same-registrar signups by creation timestamp to spot clusters
name_servers Shared nameservers Compare across signups, unfamiliar nameservers repeating is the flag
registrant_contact.email_address (not shown above, privacy-dependent) Reused registrant emails Present only when WHOIS privacy is off, compare across signups when available

The response also nests a registry_data object with the same core fields sourced separately from the registry rather than the registrar, useful as a cross-check if the two ever disagree, but not required for the basic age check shown here.

Where This Approach Breaks Down

Being upfront about the limits matters more than the pitch. WHOIS-based fraud detection has real gaps:

  • Privacy-protected domains are common and mostly innocent. Services like WhoisGuard or GDPR-driven redaction hide the registrant fields for a huge share of legitimate domains. Do not treat privacy protection itself as a red flag.
  • A compromised domain has clean history. An attacker who takes over a ten-year-old legitimate domain inherits its clean registration age. Domain age alone will miss this entirely, it needs pairing with DNS or hosting changes to catch.
  • New businesses register new domains constantly. A two-day-old domain backing a genuine new startup will look identical to a fraud signal on this metric alone. This is exactly why domain age should never be a sole blocking condition.
  • This is one signal, not a fraud engine. Pair it with email validation, IP reputation, and behavioral signals like signup velocity if fraud is a meaningful cost center for your product.

A Practical Workflow You Can Add This Week

Five-step workflow infographic for adding a WHOIS-based fraud detection API check to signup validation: extract domain, query WHOIS API, score the result, route by risk, log every check

  1. On signup, extract the domain from the company website or work email
  2. Query a WHOIS API for creation date, registrant email (if not privacy-protected), and nameservers
  3. Score the result using something like the table above rather than a single hard rule
  4. Route high-score signups to manual review or step-up verification, never an instant hard block
  5. Log every flagged signup with its WHOIS snapshot, so patterns across signups become visible over time, not just one at a time

FAQ

What is a WHOIS API used for in fraud detection?
It pulls structured registration data, creation date, registrant fields, registrar, and nameservers, for a domain, which can be checked programmatically at signup instead of relying on a human glancing at a website.

Can attackers hide from WHOIS-based fraud checks?
Partially. WHOIS privacy protection hides registrant details, and a compromised legitimate domain has clean registration history. Domain age and registrar patterns still show through privacy protection, which is why age-based checks remain useful even when registrant fields are hidden.

Is domain age alone a reliable fraud signal?
No. It is a useful, cheap first filter, but new legitimate businesses also register new domains. Domain age should route a signup to review, not trigger an automatic block.

Do I need a paid WHOIS API for this, or does a free tier work?
A free tier is usually enough to prototype the age-check pattern shown above. Higher-volume production use, or needing historical WHOIS records for older signups, typically requires a paid plan. Check your provider's current limits before committing to an architecture.

How is this different from just checking a website's SSL certificate?
An SSL certificate confirms encryption is set up, not that the business behind it is real. Certificates are often free and automatic, and tell you nothing about who registered the domain or when. WHOIS data speaks directly to ownership and timing, which is the actual fraud signal.

Where to Start

You do not need a full fraud detection API budget to try this. WhoisFreaks provides a WHOIS API with a free tier suitable for testing the domain-age check end to end, create a free account to get an API key and follow along with the code above using your own domains.

The fastest path to a working prototype:

  1. Grab an API key from your WhoisFreaks account and set it as WHOIS_API_KEY in your environment, never in code
  2. Run the domain age check against a handful of your own recent signups first, so you can see real ageInDays numbers before deciding on a threshold
  3. Start with domain age alone as a review-flag, not a block, and add the other three patterns once the first one is stable in production
  4. Log every WHOIS lookup result alongside the signup, so six months from now you have real data to tune the risk-score table instead of guessing again

The same approach works with any WHOIS provider that returns a creation date and registrant fields, so pick whichever fits your existing stack. Either way, start with the single cheapest check: domain age on signup. It catches more than its simplicity suggests.

Top comments (0)