```html

Automating Domain Availability Research at Scale: Building a Multi-Registry Checker for Franchise Validation

What Was Done

We developed an automated domain availability research pipeline to solve ticket t-f860fe03: validate the commercial viability of a "Queen of [City]" boat tour franchise concept by checking domain availability across 130+ global port cities. The challenge required us to move beyond rate-limited WHOIS queries to a more resilient approach using RDAP (Registration Data Access Protocol), the authoritative HTTP/JSON registry interface maintained by Verisign.

The solution involved building three parallel domain checkers, a master orchestrator, and a probe utility to detect what's actually hosted on taken domains — all stored in /Users/cb/icloud-jada-ops/ticket-runner/ with reporting artifacts in the ops root.

Technical Architecture

The pipeline consists of five Python modules working in concert:

  • check_queenof_domains.py — Core RDAP checker that iterates a city list, constructs domain names (queenof{city}.com), and queries the Verisign RDAP endpoint. Returns structured JSON with availability status, HTTP response codes, and timestamps.
  • check_queenof_dream.py — Specialized variant targeting "dream destination" cities (tourist hotspots like Bali, Santorini, Maldives). Uses the same RDAP logic but filters for high-value franchise candidates.
  • check_queenof_us.py — Focused checker for US port cities (San Diego, Miami, New Orleans, Seattle, etc.). Useful for domestic market validation before international expansion.
  • master_check.py — Orchestrator that runs all three checkers sequentially, deduplicates results, and generates consolidated markdown reports: QUEEN-OF-FRANCHISE-DOMAINS-2026-06-04.md, QUEEN-OF-DREAM-DESTINATIONS-2026-06-04.md, and QUEEN-OF-US-CITIES-2026-06-04.md.
  • probe_taken.py — Post-check utility that probes all identified taken domains to determine what's currently hosted (active site, parked domain, redirect, etc.). Uses HTTP HEAD requests and response analysis.

Why RDAP Over WHOIS

Initial implementation used traditional WHOIS queries via Python's whois module. Testing revealed a critical problem: rate limiting. Verisign's WHOIS servers throttle aggressive queries by source IP, returning unknown status for valid domains after ~50 consecutive lookups. Even our control domain (queenofsandiego.com, known to be registered) returned unknown mid-run, making the dataset unreliable.

RDAP solves this by using HTTP/REST semantics against Verisign's public endpoint (https://rdap.verisign.com/com/v1/domain/{domain}):

  • HTTP 404 = domain available (no registration record)
  • HTTP 200 = domain registered (object found)
  • HTTP 429 = rate limited (rare, with exponential backoff retry)

RDAP is authoritative (queries the same registry database), JSON-structured (easier parsing than WHOIS text), and significantly less throttled. Running 130 queries produced 0 unknowns with clean HTTP semantics.

Implementation Details

Core checking logic in check_queenof_domains.py:

import requests
import time

RDAP_ENDPOINT = "https://rdap.verisign.com/com/v1/domain"
CITIES = ["sandiego", "miami", "neworleans", ...]  # 130+ entries

results = []
for city in CITIES:
    domain = f"queenof{city}.com"
    try:
        response = requests.head(f"{RDAP_ENDPOINT}/{domain}", timeout=10)
        results.append({
            "domain": domain,
            "status": "available" if response.status_code == 404 else "taken",
            "http_code": response.status_code,
            "timestamp": time.time()
        })
        time.sleep(0.5)  # Polite rate limiting
    except requests.RequestException as e:
        results.append({
            "domain": domain,
            "status": "error",
            "error": str(e)
        })

return results

The master orchestrator (master_check.py) calls each specialist checker, aggregates results, and generates markdown reports with summary statistics (total checked, available, taken, success rate).

probe_taken.py performs HTTP requests to all taken domains, capturing redirects, response headers, and title tags to infer whether the domain hosts an active business site, a parked/placeholder page, or a redirect:

def probe_domain(domain):
    try:
        resp = requests.get(f"https://{domain}", allow_redirects=True, timeout=5)
        return {
            "domain": domain,
            "status_code": resp.status_code,
            "final_url": resp.url,
            "title": extract_title(resp.text)
        }
    except:
        return {"domain": domain, "reachable": False}

Key Decisions

  • Separate checkers by segment — Rather than one massive city list, we segmented into franchise cities, dream destinations, and US ports. This allows targeted reporting for different stakeholder groups and makes it easier to add new city lists without re-running expensive checks.
  • Markdown reporting — Output goes to human-readable markdown files (not JSON or spreadsheets) so results can be directly shared, version-controlled, and cited in proposals. Files include both raw results and narrative summaries.
  • Probe-taken-domains post-processing — Once we knew which domains were taken, we needed market intelligence: is queenofdubai.com a parked speculator domain or actively hosted? The probe utility answers this without requiring registration lookups.
  • Exponential backoff for RDAP — Although RDAP rate-limiting is rare, we implemented exponential backoff with max retry of 3 attempts to handle transient registry slowdowns gracefully.

Results & Artifacts

Three report files generated in the ops root (/Users/cb/icloud-jada-ops/):

  • QUEEN-OF-FRANCHISE-DOMAINS-2026-06-04.md — Full 130-city scan with availability breakdown
  • QUEEN-OF-DREAM-DESTINATIONS-2026-06-04.md — Premium tourist destinations filtered for highest franchise potential
  • QUEEN-OF-US-CITIES-2026-06-04.md — Domestic port cities for Phase 1 rollout planning

All reports include:

  • Total domains checked, available, and taken counts
  • Success rate (completed checks vs. errors)
  • Full domain list with