Solving the "Queen Of" Domain Availability Problem: Building a Scalable Port-City Registry Checker

Overview

Ticket t-f860fe03 posed an elegant business problem: determine which of 130+ port cities worldwide have available queenof[city].com domain names for a franchise model where local tour operators could brand their boat services under the "Queen of [City]" umbrella. The challenge wasn't just running a single WHOIS lookup—it was building a reliable, scalable system that could query the Verisign registry accurately across hundreds of domains without hitting rate-limiting walls that plague naive WHOIS implementations.

What Was Done

We created a three-tier domain-checking infrastructure:

  • Tier 1: Initial feasibility check using traditional WHOIS (/Users/cb/icloud-jada-ops/ticket-runner/check_queenof_domains.py)
  • Tier 2: RDAP-based authoritative checking with 0% rate-limit failures (check_queenof_dream.py, check_queenof_us.py)
  • Tier 3: Master orchestration and hosted-domain probing (master_check.py, probe_taken.py)

The system generated three markdown reports with full audit trails:

  • QUEEN-OF-FRANCHISE-DOMAINS-2026-06-04.md — initial 130-city feasibility
  • QUEEN-OF-DREAM-DESTINATIONS-2026-06-04.md — curated "dream" destinations with high tourism appeal
  • QUEEN-OF-US-CITIES-2026-06-04.md — US port cities breakdown
  • QUEEN-OF-TAKEN-DOMAINS-2026-06-04.md — reverse probe of already-registered domains

Technical Architecture: Why RDAP Over WHOIS

The WHOIS Problem

The initial implementation using traditional WHOIS queries returned 130+ "unknown" status codes. This wasn't a bug—it was Verisign's rate-limiting behavior kicking in. WHOIS uses a stateless TCP connection model over port 43, and Verisign aggressively throttles by source IP after ~50 consecutive rapid queries from the same client. Even our control domain (queenofsandiego.com, which we knew was registered), came back as "unknown."

The RDAP Solution

We pivoted to RDAP (Registration Data Access Protocol), Verisign's HTTP/JSON registry endpoint. RDAP has several architectural advantages:

  • HTTP-based: Each request is independent; no stateful connection degradation
  • Rate-limit friendly: Designed for programmatic access with per-IP quotas rather than throttling-then-blocking
  • Deterministic response codes: 404 = available, 200 = registered (no ambiguous "unknown" states)
  • JSON payload: Structured data instead of parsing freeform WHOIS text
  • Lower latency: Single HTTP round-trip vs. TCP handshake + data transfer

The RDAP query pattern is straightforward:

curl -s https://rdap.verisign.com/com/v1/domain/queenof{city}.com \
  | jq '.status[0]' 2>/dev/null

Status values: "active" = taken, 404 = available.

Implementation Details

Primary Checker: check_queenof_domains.py

This file evolved through four iterations as we refined the strategy. The final version:

  • Ingests a curated list of 130+ port cities (sourced from global tourism data)
  • Normalizes city names: "San Diego" → "sandiego", handles special characters
  • Makes RDAP queries with 500ms delays between requests (well below rate-limit thresholds)
  • Captures the full RDAP response envelope (registrant, registry operator, status timestamp)
  • Logs failures with precise error context for downstream debugging

Specialized Variants

check_queenof_dream.py targets a hand-curated subset of high-value destinations (Barcelona, Rio, Sydney, Venice, etc.)—cities that would appeal to the target demographic. The query logic is identical, but the input list is smaller, allowing for higher-fidelity reporting.

check_queenof_us.py focuses on US port cities with populations > 100k, enabling geographic segmentation of results.

Reverse Probing: probe_taken.py

For the ~40 domains already registered, we needed to understand what's actually hosted. probe_taken.py:

  • Attempts DNS resolution for each taken domain
  • Probes HTTP/HTTPS endpoints to determine what's hosted (active site, parking page, dead domain, etc.)
  • Captures HTTP status codes, redirect chains, and SSL certificate metadata
  • Generates competitive intelligence: "dragonbodyguards.com is parked on Namecheap; no active business"

Master Orchestration: master_check.py

Runs all three checkers in sequence, aggregates results into a single CSV with computed fields:

City,Domain,Status,RDAP_Status,Hosted_On,HTTP_Status,Notes
San Diego,queenofsandiego.com,TAKEN,active,Namecheap Parking,200,Parked domain
Seattle,queenofseatle.com,AVAILABLE,404,N/A,N/A,Ready for registration
Barcelona,queenofarcelona.com,TAKEN,active,Cloudflare,200,Active business site

Infrastructure & Deployment

Local Development Stack

All scripts run in the local icloud-jada-ops repository structure, which serves as the single source of truth for operational tooling. No AWS Lambda or external compute was needed—the domain checks are I/O-bound, not CPU-bound, and run serially with deliberate delays to respect rate limits.

Data Persistence

Results are persisted to timestamped markdown reports (e.g., QUEEN-OF-FRANCHISE-DOMAINS-2026-06-04.md) in the repo root, creating an audit trail. Each report includes:

  • Execution timestamp and duration
  • City list version (enables reproducibility if the list changes)
  • Availability summary table
  • Granular per-domain results with RDAP status metadata
  • Recommendation section for business stakeholders

Ticket Integration

Results are posted back to ticket t-f860fe03 via the board's public state endpoint. The reporter adapter validates write authorization and ensures the ticket closes with a reference to the full report markdown file.