Scaling Domain Availability Research with RDAP: Building the Queen-of-Cities Franchise Validation System
What Was Done
Ticket t-f860fe03 required validating a franchise concept: determining how many port cities worldwide have available queenof[city].com domains for a boat-tour operator brand. The challenge was building a reliable, scalable domain-checker that could probe 130+ cities without hitting rate limits or returning false positives.
We built a three-tier validation pipeline:
- Python domain-checker scripts in
/Users/cb/icloud-jada-ops/ticket-runner/ - RDAP-based registry lookups (avoiding whois throttling)
- Master orchestration runner that consolidates results across three domain prefixes
- Markdown report generation for ticket handoff
Why WHOIS Failed (And How RDAP Solved It)
Our first approach used traditional whois queries. The control test was brutal: queenofsandiego.com (known to be registered) returned unknown due to Verisign throttling. Out of 130 queries, we got ~80 unknowns—useless for decision-making.
Root cause: WHOIS is a legacy TCP protocol. Verisign rate-limits aggressively by source IP. Each query from a single machine hits the throttle bucket harder, causing timeout responses.
The RDAP pivot: RDAP (Registration Data Access Protocol) is the HTTP/JSON successor to WHOIS. Verisign's RDAP endpoint returns:
HTTP 404= domain available (no registration object)HTTP 200= domain registered (object returned)- Far fewer rate-limit issues (HTTP has better backoff semantics)
RDAP queries for the same 130 cities yielded zero unknowns and correctly identified queenofsandiego.com as taken.
Technical Architecture
Core Checker: check_queenof_domains.py
Located at /Users/cb/icloud-jada-ops/ticket-runner/check_queenof_domains.py, this script:
- Takes a city list and domain prefix (e.g.,
queenof) - Builds FQDN:
queenof[city].com - Issues RDAP HTTP request to
https://rdap.verisign.com/com/v1/domain/[fqdn] - Parses response code (404 = available, 200 = taken)
- Logs results with timestamp and status
- Writes markdown report with availability summary
Example invocation (pseudocode—actual version in repo):
python check_queenof_domains.py --prefix queenof --cities port_cities.txt --output QUEEN-OF-FRANCHISE-DOMAINS-2026-06-04.md
Specialized Variants for Different City Lists
We built three parallel checkers, each targeting a different segment:
check_queenof_dream.py– Dream vacation destinations (Maldives, Bali, Caribbean, etc.)check_queenof_us.py– US port cities (Boston, Charleston, Miami, Seattle, etc.)check_queenof_domains.py(original) – Franchise-tier port cities worldwide
Each generates its own markdown report:
QUEEN-OF-FRANCHISE-DOMAINS-2026-06-04.mdQUEEN-OF-DREAM-DESTINATIONS-2026-06-04.mdQUEEN-OF-US-CITIES-2026-06-04.md
Master Orchestration: master_check.py
Located at /Users/cb/icloud-jada-ops/ticket-runner/master_check.py, this script:
- Calls all three specialized checkers sequentially
- Consolidates results into a single execution
- Produces unified reporting for the ticket system
- Provides a single entry point for CI/CD integration
Domain Probe: probe_taken.py
For domains flagged as "taken," we needed to know what's actually hosted there. The probe script:
- Attempts HTTP/HTTPS connections to taken domains
- Captures status codes, redirects, and server headers
- Generates report
QUEEN-OF-TAKEN-DOMAINS-2026-06-04.md - Helps identify if domains are parked, in-use, or abandoned
This data informs whether to pursue acquisition or alternatives.
Key Technical Decisions
1. RDAP Over WHOIS
Decision: Abandon whois; implement RDAP with retry logic.
Rationale: WHOIS is fundamentally rate-limited and unstructured. RDAP provides HTTP semantics (caching, backoff headers), JSON parsing, and better throttle recovery. For a batch job over 130+ domains, reliability matters more than legacy compatibility.
2. Separate Checkers Per City List
Decision: Three specialized scripts rather than one parameterized mega-script.
Rationale: Different stakeholders care about different segments (franchise operators care about port cities; marketing cares about dream destinations). Separate scripts allow independent scheduling, targeted reporting, and easier pivots if one segment's data model changes. Code duplication is minimal; the RDAP core is shared.
3. Markdown Reports as Primary Output
Decision: Generate .md files rather than JSON or CSV.
Rationale: Tickets expect human-readable output. Markdown can be pasted directly into ticket systems, rendered in GitHub, and archived. It's self-documenting (includes metadata like execution time, city count, available/taken ratio).
4. Probe Taken Domains for Content
Decision: Add HTTP probing to identify what's running on taken domains.
Rationale: "Taken" doesn't equal "unavailable." A parked GoDaddy domain may be acquirable; an active business site is not. Probing redirects and server signatures tells us whether to pursue WHOIS lookups for contact info.
Data Flow
City List → Checker Script → RDAP Query → HTTP 404/200 → Markdown Report → Ticket Update
↓
(if taken) → Probe Script → HTTP Probe → Content Report