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 locationscheck_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 analysisQUEEN-OF-DREAM-DESTINATIONS-2026-06-04.md– Luxury destination analysisQUEEN-OF-US-CITIES-2026-06-04.md– Domestic market analysisQUEEN-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