DEV Community

Alex Spinov
Alex Spinov

Posted on

There's a Free WHOIS API — Look Up Any Domain's Registration Data Programmatically

I was researching a suspicious email. The sender's domain was registered 3 days ago. That's a red flag.

I found it using a free WHOIS API — no key, no signup, just a GET request.

The Free WHOIS APIs

Several services offer free WHOIS lookups via API:

1. RDAP (Registration Data Access Protocol)

RDAP is the official replacement for WHOIS, maintained by IANA. It returns structured JSON.

import requests

def rdap_lookup(domain):
    # RDAP bootstrap finds the right registry automatically
    resp = requests.get(f'https://rdap.org/domain/{domain}')
    if resp.status_code != 200:
        return {'error': f'Status {resp.status_code}'}

    data = resp.json()

    # Extract key info
    result = {'domain': domain}

    # Registration dates
    for event in data.get('events', []):
        if event['eventAction'] == 'registration':
            result['registered'] = event['eventDate'][:10]
        elif event['eventAction'] == 'expiration':
            result['expires'] = event['eventDate'][:10]
        elif event['eventAction'] == 'last changed':
            result['updated'] = event['eventDate'][:10]

    # Nameservers
    result['nameservers'] = [
        ns.get('ldhName', '') 
        for ns in data.get('nameservers', [])
    ]

    # Status
    result['status'] = data.get('status', [])

    return result

# Example
info = rdap_lookup('google.com')
for k, v in info.items():
    print(f"  {k}: {v}")
Enter fullscreen mode Exit fullscreen mode

Output:

  domain: google.com
  registered: 1997-09-15
  expires: 2028-09-14
  updated: 2019-09-09
  nameservers: ['ns1.google.com', 'ns2.google.com', ...]
  status: ['client delete prohibited', 'server update prohibited']
Enter fullscreen mode Exit fullscreen mode

2. Check Domain Age (Security Signal)

from datetime import datetime

def check_domain_age(domain):
    info = rdap_lookup(domain)
    if 'registered' not in info:
        return {'domain': domain, 'risk': 'UNKNOWN', 'reason': 'No registration date found'}

    reg_date = datetime.strptime(info['registered'], '%Y-%m-%d')
    age_days = (datetime.now() - reg_date).days

    if age_days < 30:
        risk = 'HIGH'
        note = f'Domain is only {age_days} days old!'
    elif age_days < 365:
        risk = 'MEDIUM'
        note = f'Domain is {age_days} days old'
    else:
        risk = 'LOW'
        note = f'Domain is {age_days // 365} years old'

    return {'domain': domain, 'risk': risk, 'age_days': age_days, 'note': note}

# Check suspicious domains
for d in ['google.com', 'totally-legit-bank.com']:
    result = check_domain_age(d)
    print(f"  {result['domain']}: {result['risk']}{result['note']}")
Enter fullscreen mode Exit fullscreen mode

3. Bulk Domain Research

import time

def research_domains(domains):
    results = []
    for domain in domains:
        info = rdap_lookup(domain)
        info['age'] = check_domain_age(domain)
        results.append(info)
        time.sleep(1)  # Be polite

    # Sort by registration date
    results.sort(key=lambda r: r.get('registered', '9999'))

    for r in results:
        age = r['age']
        print(f"  {r['domain']:<30} reg:{r.get('registered','?'):<12} {age['risk']}")

    return results

# Research competitor domains
research_domains(['stripe.com', 'square.com', 'paypal.com'])
Enter fullscreen mode Exit fullscreen mode

4. Find Nameserver Patterns

from collections import Counter

def analyze_nameservers(domains):
    ns_counter = Counter()
    for domain in domains:
        info = rdap_lookup(domain)
        for ns in info.get('nameservers', []):
            # Extract provider from nameserver
            provider = ns.split('.')[-2] if '.' in ns else ns
            ns_counter[provider] += 1
        time.sleep(1)

    print('Nameserver providers:')
    for ns, count in ns_counter.most_common(5):
        print(f'  {ns}: {count} domains')
Enter fullscreen mode Exit fullscreen mode

Use Cases

  1. Security: Flag newly registered domains in phishing emails
  2. Due diligence: Verify company claims about their founding date
  3. SEO: Check domain age before purchasing expired domains
  4. Competitive intelligence: Track when competitors register new domains
  5. Brand protection: Monitor for typosquat domain registrations

Rate Limits

  • RDAP: No official rate limit, but registries may throttle
  • Add 1-second delays between requests
  • Cache results — domain data doesn't change often

Building security and research tools with free APIs. More projects: GitHub | Writing: Spinov001@gmail.com

Top comments (0)