```html

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.md
  • QUEEN-OF-DREAM-DESTINATIONS-2026-06-04.md
  • QUEEN-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