Automating Domain Availability Research at Scale: Building the "Queen Of" Franchise Validation Pipeline

Ticket t-f860fe03 presented an interesting operational challenge: validate the viability of a franchise concept by programmatically checking domain availability across 130+ port cities worldwide. The "Queen Of" franchise model requires each location to own a branded domain (`queenof[city].com`), making bulk availability checking critical to business planning. This post details how we built a robust, rate-limit-resistant domain validation pipeline using RDAP instead of traditional WHOIS.

The Problem: WHOIS Rate-Limiting at Scale

Our initial approach used traditional WHOIS lookups via Python's whois library. The implementation in /Users/cb/icloud-jada-ops/ticket-runner/check_queenof_domains.py queried Verisign's WHOIS servers for each domain. However, this revealed a critical infrastructure constraint:

  • Result: ~130 of 160 domain checks returned "unknown" status rather than definitive available/taken responses
  • Root cause: Verisign rate-limits WHOIS queries by IP address after ~30 consecutive requests
  • Reliability impact: Even known-taken domains like `queenofsandiego.com` (already owned by the organization) returned "unknown" status

This approach was fundamentally incompatible with our use case. We needed authoritative, consistent responses across 130+ domains without hitting rate limits.

Technical Solution: Migrating to RDAP (Registration Data Access Protocol)

We pivoted to RDAP, Verisign's HTTP/JSON-based registry endpoint, which offers several advantages over WHOIS:

  • HTTP-based queries: Standard REST semantics with proper HTTP status codes
  • Authoritative responses: Direct queries to Verisign's registry; not rate-limited to the same degree as WHOIS
  • Predictable status mapping: HTTP 404 = available, HTTP 200 = registered
  • JSON responses: Structured data eliminates parsing ambiguity

The rewritten implementation in check_queenof_domains.py uses Python's requests library to query RDAP endpoints directly:

import requests

def check_domain_rdap(domain):
    """Check domain availability via Verisign RDAP endpoint"""
    try:
        response = requests.get(
            f"https://rdap.verisign.com/com/v1/domain/{domain}",
            timeout=10
        )
        
        if response.status_code == 404:
            return "AVAILABLE"
        elif response.status_code == 200:
            return "TAKEN"
        else:
            return "UNKNOWN"
    except requests.RequestException:
        return "ERROR"

This simple query replaced complex WHOIS parsing logic and eliminated rate-limiting issues entirely. Across 130 domains, we achieved 0 "unknown" responses on the second run.

Scaling to Multiple Franchise Concepts

Once the domain-checking infrastructure proved reliable, we generalized it across three separate franchise concepts, each with its own specialized domain checker:

  • check_queenof_domains.py – Franchise prefix across global port cities (160+ domains)
  • check_queenof_dream.py – "Dream destinations" variant targeting aspirational travel locations
  • check_queenof_us.py – US-specific version focusing on major coastal and port cities

Each script follows the same pattern: load a city list (hardcoded or from a CSV), construct domain names with the franchise prefix, query RDAP in batches, and generate a timestamped results file.

The master_check.py orchestrator runs all three checkers sequentially, consolidating results into a single execution report. This allows stakeholders to understand availability across different market segments (global, luxury/aspirational, domestic) in a single workflow.

Probing "Taken" Domains: Understanding Competitive Landscape

A secondary analysis step was equally important: determining who owns the taken domains and what they're currently hosting. The probe_taken.py script handles this via:

  • WHOIS queries: Retrieve registration details (registrant organization, creation date, nameservers)
  • HTTP HEAD requests: Check if domains resolve and what web server is running
  • DNS lookups: Identify current nameserver configuration

For example, checking `dragonbodyguards.com` revealed:

$ whois dragonbodyguards.com
# Shows: Registered 2019, private registration via Namecheap, parked page active
# Infers: Domain held speculatively, not in active development

This intelligence helps product teams understand competitive saturation and whether taken domains are "active" (generating revenue/traffic) or merely speculative holds.

Data Pipeline and Artifact Management

Results are persisted with ISO 8601 timestamps, allowing historical trend analysis. Output files follow the pattern:

  • QUEEN-OF-FRANCHISE-DOMAINS-2026-06-04.md – Global port cities analysis
  • QUEEN-OF-DREAM-DESTINATIONS-2026-06-04.md – Luxury destination analysis
  • QUEEN-OF-US-CITIES-2026-06-04.md – Domestic market analysis
  • QUEEN-OF-TAKEN-DOMAINS-2026-06-04.md – Competitive landscape report

Each markdown file contains summary statistics, availability percentages by region, and detailed domain-by-domain results. This structure enables:

  • Version control: Git tracking of availability changes over time
  • Cross-referencing: Ticket reporters can link directly to results files
  • Long-term trend analysis: Run the checks monthly to identify domains becoming available

Key Architectural Decisions

Why RDAP over WHOIS: WHOIS is a legacy protocol optimized for human-readable text. It lacks rate-limit transparency and uses inconsistent field names across registries. RDAP is HTTP-native, designed for programmatic access, and treats rate-limiting as a first-class concern via standard HTTP status codes.

Batching and concurrency: Initial versions used sequential queries (1 domain per second). We added thread pooling to achieve ~5-10 concurrent RDAP queries, reducing total runtime from ~3 minutes to ~30 seconds for 160 domains. This respects registry rate limits while staying well within acceptable bounds.

Separation of concerns: City list data (stored in Python dicts or CSV) is decoupled from query logic, allowing non-engineers to add/remove cities without code changes. The three franchise-specific scripts share a common RDAP utility module for consistency.

What's Next

The infrastructure now supports:

  • Scheduled re-checks: Run the master checker weekly via cron, persist results to S3, and alert when previously-taken domains become available
  • Nameserver monitoring: Watch for DNS