```html

Domain Availability Research at Scale: Building a Port-City Franchise Validator with RDAP and Python

What Was Done

Ticket t-f860fe03 requested research into domain availability for a "Queen of [City]" franchise concept—a distributed tour operator business model where each port city could register queenof[city].com as a branded local entity. The challenge: determine how many of ~130 port cities worldwide have available domains, and do so reliably and at scale.

Over this session, we built and deployed three independent domain checkers (check_queenof_domains.py, check_queenof_dream.py, check_queenof_us.py), a master coordinator (master_check.py), and a hosting probe (probe_taken.py) to answer the research question and validate infrastructure assumptions.

The WHOIS Problem and Why We Switched to RDAP

Initial approach used the whois command-line tool via Python subprocess. This failed catastrophically:

  • Rate limiting: Verisign (the .com registry) throttles whois queries by source IP. After ~20 queries, responses became "unknown" rather than authoritative.
  • Unreliability: Even known-taken domains like queenofsandiego.com returned "unknown" under load, making results untrustworthy for reporting.
  • No programmatic structure: WHOIS returns free-form text requiring fragile regex parsing.

Solution: RDAP (Registration Data Access Protocol). Verisign operates a public RDAP endpoint at https://rdap.verisign.com/com/v1/domain/ which:

  • Returns structured JSON (no parsing fragility).
  • Uses HTTP caching and is far less throttled than WHOIS.
  • Provides authoritative answers: 404 = available, 200 = registered.
  • Supports bulk queries without IP-level rate limiting.

Architecture: Three Parallel Checkers + Master Coordinator

Rather than a single monolithic checker, we built a three-domain-list architecture:

  • /Users/cb/icloud-jada-ops/ticket-runner/check_queenof_domains.py — Top-12 port cities (San Diego, Singapore, Dubai, Hong Kong, etc.). This became the primary validation target.
  • check_queenof_dream.py — Dream destinations (Barcelona, Bora Bora, Santorini, etc.) — aesthetic/lifestyle focus.
  • check_queenof_us.py — US-only cities (Miami, New York, Los Angeles, etc.) — domestic market potential.

Each checker generates a timestamped markdown report (QUEEN-OF-*.md) with results, counts, and available domains listed for action.

master_check.py coordinates all three, runs them sequentially, and aggregates results into a single decision artifact.

Implementation: RDAP Query Logic

Core pattern (pseudo-code; actual implementation in check_queenof_domains.py):

import requests

RDAP_ENDPOINT = "https://rdap.verisign.com/com/v1/domain/"

def check_domain(domain):
    try:
        response = requests.get(f"{RDAP_ENDPOINT}{domain}", timeout=5)
        if response.status_code == 404:
            return "AVAILABLE"
        elif response.status_code == 200:
            return "TAKEN"
        else:
            return "UNKNOWN"
    except requests.RequestException:
        return "ERROR"

Key decisions:

  • Timeout of 5 seconds: RDAP is fast; anything slower likely indicates network issues.
  • Status codes as source of truth: We ignore response body for the availability determination; the HTTP status code is definitive.
  • Batching with short delays: To avoid any appearance of DOS, we added 0.5-second delays between queries even though RDAP doesn't rate-limit per-IP.
  • Retry logic: Transient timeouts retry once before marking as ERROR.

Validation: The Control Domain

We included queenofsandiego.com as a known-taken control. When WHOIS failed to identify it as taken, we knew we had a problem. When RDAP correctly returned 200 (TAKEN) for that domain, it validated the entire approach.

This is a critical QA pattern: always include a known-good and known-bad sample in bulk registry queries.

Hosting Probe: What's Actually Running?

probe_taken.py follows up on the registered domains: it performs HTTP/HTTPS requests to each "TAKEN" domain to determine:

  • Is it parked? (typical registrar landing page)
  • Does it redirect? (to what domain/service?)
  • Is it active? (200 response with actual content)
  • What IP/CDN is serving it?

This uncovers opportunities: a domain registered but parked (no active service) might be purchasable. A domain in active use by a competitor needs different strategy.

Reporting and Integration

Each checker writes results to a timestamped markdown file:

  • QUEEN-OF-FRANCHISE-DOMAINS-2026-06-04.md (Top-12 cities)
  • QUEEN-OF-DREAM-DESTINATIONS-2026-06-04.md (Dream cities)
  • QUEEN-OF-US-CITIES-2026-06-04.md (US cities)

Format includes:

  • Summary counts: Total queried, available, taken, errors.
  • Available domains list: Actionable inventory for franchise expansion.
  • Taken domains list: For competitor/adjacent research.
  • Metadata: Run timestamp, RDAP endpoint version, timeout settings.

Key Decisions: Why This Architecture?

  • Separate checkers instead of one monolith: Allows independent scheduling, different retry logic for different city lists, and cleaner git history for domain list changes.
  • RDAP over WHOIS: Structured data, HTTP (cacheable), less rate-limited, and no parsing fragility.
  • Markdown reports instead of JSON: Human-readable, git-friendly, embeddable in tickets and documentation.