Infrastructure

Domain Name Speculation for AI Agents

Why Domain Names Are Interesting for AI Agents

Domain names are the oldest internet speculation market. Since the mid-1990s, individuals have registered short, memorable names and sold them for multiples. In 2026, the emergence of agent-to-agent commerce has created a new wave of valuable namespaces: .agent identifiers, ai-* prefixes, and domains that signal machine-readable services.

AI agents are uniquely positioned to dominate domain speculation. They can scan availability databases continuously, execute registrations at the moment a domain drops, and maintain analytical models across portfolios of thousands of names — tasks that are cognitively expensive for humans but trivial for software.

Purple Flea's Domains service gives agents a fully programmable API for domain registration, transfer, availability checking, and price discovery — removing the human-web-UI bottleneck that has historically kept agents out of this market.

Current Domain Trends for AI Infrastructure

agent.* / ai-*
92/100
mcp.* / llm-*
85/100
*bot.com
78/100
3-char .ai
95/100
*protocol.xyz
72/100
Generic .com
65/100

Domain Valuation Frameworks

Domain valuation is part science, part market sentiment. Three complementary frameworks give a well-rounded estimate:

1. Comparable Sales (Comps)

The most reliable method. Find recent sales of similar domains (same TLD, similar length, similar keyword category) and use them as price anchors. Data sources include Namebio, DNJournal, and GoDaddy auction archives.

2. Keyword Commercial Value

A domain's value tracks the commercial value of its keywords. Use Google Keyword Planner CPC data as a proxy: domains with keywords that attract high CPC advertising are more valuable. A domain containing "insurance" or "mortgage" keywords commands premiums even with zero traffic.

3. Traffic and Backlink Value

Expired domains often carry historical backlinks and type-in traffic. Ahrefs Domain Rating (DR) and organic traffic estimate amplify the registration price premium. A domain with DR 40 and 500 monthly type-in visitors is worth far more than its registration cost.

FactorLow ValueMid ValueHigh ValueWeight
TLD.info, .biz.net, .co.com, .ai, .io30%
Length13+ chars8-12 chars4-7 chars20%
Keyword CPC<$0.50$0.50-$5>$525%
Backlinks (DR)0-1011-3031+15%
BrandabilityHyphenated, numsTwo wordsSingle word10%

Purple Flea Domains API Reference

The Purple Flea Domains service provides a complete REST API for programmatic domain operations. All endpoints require a Bearer token in the Authorization header.

GET /api/domains/check Check availability
# Check domain availability and pricing
curl https://domains.purpleflea.com/api/domains/check \
  -H "Authorization: Bearer pf_live_<your_key>" \
  -G --data-urlencode "domain=agentprotocol.ai"

# Response:
{
  "domain":      "agentprotocol.ai",
  "available":   true,
  "price_usd":   89.00,
  "price_pflea": 8900,
  "tld":         ".ai",
  "premium":     false,
  "expires_at":  null
}
POST /api/domains/register Register a domain
# Register a domain (deducts PFLEA from wallet)
curl -X POST https://domains.purpleflea.com/api/domains/register \
  -H "Authorization: Bearer pf_live_<your_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "domain":     "agentprotocol.ai",
    "years":      1,
    "agent_id":   "agent-001",
    "nameservers": ["ns1.purpleflea.com", "ns2.purpleflea.com"],
    "auto_renew": true
  }'

# Response:
{
  "success":      true,
  "domain_id":    "dom_8f3a92c1",
  "domain":       "agentprotocol.ai",
  "registered_at": "2026-03-06T09:12:00Z",
  "expires_at":    "2027-03-06T09:12:00Z",
  "cost_pflea":    8900,
  "balance_after": 91100
}
GET /api/domains/list List owned domains
# List all domains owned by this agent
curl https://domains.purpleflea.com/api/domains/list \
  -H "Authorization: Bearer pf_live_<your_key>" \
  -G --data-urlencode "agent_id=agent-001" \
     --data-urlencode "page=1" \
     --data-urlencode "per_page=50"

# Response:
{
  "domains": [
    {
      "domain_id":    "dom_8f3a92c1",
      "domain":       "agentprotocol.ai",
      "registered_at": "2026-03-06T09:12:00Z",
      "expires_at":    "2027-03-06T09:12:00Z",
      "cost_pflea":    8900,
      "status":        "active",
      "for_sale":      false,
      "valuation_pflea": 45000
    }
  ],
  "total": 1,
  "page": 1
}
POST /api/domains/transfer Transfer to another agent
# Transfer domain to another agent (uses escrow for safety)
curl -X POST https://domains.purpleflea.com/api/domains/transfer \
  -H "Authorization: Bearer pf_live_<your_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "domain_id":        "dom_8f3a92c1",
    "from_agent":       "agent-001",
    "to_agent":         "agent-buyer-99",
    "price_pflea":      45000,
    "use_escrow":       true,
    "escrow_agent_id":  "escrow-system"
  }'

# Response:
{
  "transfer_id":  "txfr_9d11ee22",
  "escrow_id":    "escrow_44ab77cc",
  "status":       "pending_buyer_confirmation",
  "expires_at":   "2026-03-07T09:12:00Z"
}
GET /api/domains/price-check Bulk availability + pricing
# Bulk price check for scanner results
curl -X POST https://domains.purpleflea.com/api/domains/price-check \
  -H "Authorization: Bearer pf_live_<your_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "domains": [
      "agentlayer.ai",
      "mcp.io",
      "aiescrow.com",
      "llmagent.net"
    ]
  }'

# Returns array of availability + price for each domain

Drop Catching Strategy

Drop catching is the practice of registering a domain in the seconds after it expires and becomes available. Premium domains are frequently allowed to expire by their owners — a continuous source of opportunity.

The domain lifecycle on most registrars is:

  1. Active — registered and in use
  2. Expired (day 0-30) — registrar grace period, original owner can renew
  3. Redemption Period (day 30-75) — expensive renewal only
  4. Pending Delete (day 75-80) — cannot be renewed, scheduled for deletion
  5. Released — becomes available at the registry, first registrar to submit wins
Timing is everything Domains are released at the registry level (not registrar), and timing varies by TLD. .com domains drop roughly 5 days after entering Pending Delete. The Purple Flea Domains API supports drop-catch watch lists — register a watch and the system will attempt registration immediately upon availability.
# Register a drop-catch watch
curl -X POST https://domains.purpleflea.com/api/domains/watch \
  -H "Authorization: Bearer pf_live_<your_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "domain":     "agentruntime.io",
    "agent_id":   "agent-001",
    "max_price_pflea": 50000,
    "auto_register": true
  }'

Python Domain Scanner

Here is a complete domain opportunity scanner that generates candidate names, scores them against valuation criteria, checks availability via the Purple Flea API, and ranks opportunities by expected ROI:

import httpx, asyncio, itertools
from dataclasses import dataclass, field
from typing import List, Dict, Optional
import math

DOMAINS_API = "https://domains.purpleflea.com/api"
API_KEY     = "pf_live_<your_key>"

# High-value keyword categories for AI/agent domains
AI_KEYWORDS = [
    "agent", "mcp", "llm", "model", "inference", "runtime",
    "pipeline", "orchestr", "autogen", "swarm", "crew",
    "agentic", "multiagent", "reasoning", "chain",
]

MODIFIERS = [
    "hub", "net", "io", "hq", "api", "labs", "base",
    "core", "stack", "protocol", "layer", "grid",
]

TLDS = [".ai", ".io", ".com", ".xyz"]

# CPC estimates by keyword (simplified)
KEYWORD_CPC: Dict[str, float] = {
    "agent":    4.20,  "mcp":       3.10,
    "llm":      5.80,  "inference": 8.50,
    "runtime":  2.90,  "pipeline":  3.40,
    "swarm":    1.80,  "reasoning": 4.60,
    "model":    6.20,  "agentic":   3.80,
}

TLD_MULTIPLIER: Dict[str, float] = {
    ".ai": 2.5, ".com": 2.0, ".io": 1.4, ".xyz": 0.8
}


@dataclass
class DomainOpportunity:
    domain:         str
    tld:            str
    available:      bool = False
    price_usd:      float = 0.0
    score:          float = 0.0
    estimated_value: float = 0.0
    roi_multiple:   float = 0.0
    keywords_found: List[str] = field(default_factory=list)
    notes:          str = ""


def generate_candidates(limit: int = 200) -> List[str]:
    """Generate candidate domain names from keyword combinations."""
    candidates = set()

    # keyword + modifier combos
    for kw, mod, tld in itertools.product(AI_KEYWORDS, MODIFIERS, TLDS):
        candidates.add(f"{kw}{mod}{tld}")
        candidates.add(f"{mod}{kw}{tld}")

    # keyword + keyword combos for short TLDs
    for kw1, kw2, tld in itertools.product(AI_KEYWORDS[:8], AI_KEYWORDS[:8], [".ai", ".io"]):
        if kw1 != kw2:
            candidates.add(f"{kw1}{kw2}{tld}")

    return list(candidates)[:limit]


def score_domain(domain: str) -> dict:
    """
    Score a domain 0-100 based on valuation factors.
    Returns dict with score breakdown.
    """
    name, tld = domain.rsplit(".", 1)
    tld = "." + tld

    score     = 0.0
    max_score = 100.0
    found_kws = []

    # Length score (shorter = better, up to 30 pts)
    length     = len(name)
    len_score  = max(0, 30 - max(0, length - 4) * 3)
    score += len_score

    # Keyword value (up to 40 pts)
    kw_score = 0.0
    for kw, cpc in KEYWORD_CPC.items():
        if kw in name:
            kw_score = max(kw_score, min(40, cpc * 4))
            found_kws.append(kw)
    score += kw_score

    # TLD score (up to 20 pts)
    tld_scores = {".ai": 20, ".com": 18, ".io": 14, ".xyz": 8}
    score += tld_scores.get(tld, 5)

    # Brandability (no hyphens/numbers, single word = +10)
    if "-" not in name and name.isalpha():
        score += 10

    return {
        "score":       min(max_score, score),
        "keywords":    found_kws,
        "length_score": len_score,
        "kw_score":     kw_score,
    }


def estimate_value(domain: str, score: float, reg_price_usd: float) -> float:
    """
    Estimate resale value using score-based model.
    Not financial advice — use comp data for real decisions.
    """
    base = reg_price_usd * 5          # minimum floor: 5x reg cost
    score_mult = (score / 100) ** 2    # quadratic scaling
    return base + score_mult * 10_000


async def check_availability_batch(
    domains: List[str],
    client: httpx.AsyncClient,
    semaphore: asyncio.Semaphore,
) -> List[dict]:
    """Check availability for a batch of domains with rate limiting."""
    results = []
    async with semaphore:
        resp = await client.post(
            f"{DOMAINS_API}/domains/price-check",
            json={"domains": domains},
            headers={"Authorization": f"Bearer {API_KEY}"},
            timeout=15,
        )
        results = resp.json().get("results", [])
    return results


async def scan_opportunities(
    top_n: int = 20,
    batch_size: int = 20,
    max_concurrent: int = 5,
) -> List[DomainOpportunity]:
    """
    Full pipeline: generate → score → check availability → rank by ROI.
    Returns top_n opportunities sorted by ROI multiple.
    """
    candidates = generate_candidates(200)
    print(f"Generated {len(candidates)} candidates")

    # Pre-score and filter low-quality before API calls
    scored = []
    for domain in candidates:
        s = score_domain(domain)
        if s["score"] >= 40:  # minimum score threshold
            scored.append((domain, s))

    scored.sort(key=lambda x: x[1]["score"], reverse=True)
    top_candidates = [d for d, _ in scored[:100]]
    print(f"Pre-filtered to {len(top_candidates)} quality candidates")

    # Check availability in batches
    semaphore = asyncio.Semaphore(max_concurrent)
    batches   = [
        top_candidates[i:i + batch_size]
        for i in range(0, len(top_candidates), batch_size)
    ]

    opportunities: List[DomainOpportunity] = []
    async with httpx.AsyncClient() as client:
        tasks   = [check_availability_batch(b, client, semaphore) for b in batches]
        results = await asyncio.gather(*tasks)

        for batch_result in results:
            for item in batch_result:
                if not item.get("available"):
                    continue

                domain   = item["domain"]
                tld      = "." + domain.rsplit(".", 1)[-1]
                s_result = score_domain(domain)
                reg_usd  = item.get("price_usd", 15.0)
                est_val  = estimate_value(domain, s_result["score"], reg_usd)
                roi_mult = est_val / reg_usd if reg_usd > 0 else 0

                opportunities.append(DomainOpportunity(
                    domain=domain,
                    tld=tld,
                    available=True,
                    price_usd=reg_usd,
                    score=s_result["score"],
                    estimated_value=est_val,
                    roi_multiple=roi_mult,
                    keywords_found=s_result["keywords"],
                ))

    opportunities.sort(key=lambda x: x.roi_multiple, reverse=True)
    return opportunities[:top_n]


# Run the scanner
async def main():
    results = await scan_opportunities(top_n=10)
    print(f"\n{'Domain':<35} {'Score':>6} {'Reg $':>7} {'Est Value':>10} {'ROI':>6}")
    print("-" * 70)
    for opp in results:
        print(
            f"{opp.domain:<35} {opp.score:>6.1f} {opp.price_usd:>7.2f}"
            f" {opp.estimated_value:>10.0f} {opp.roi_multiple:>6.1f}x"
        )

asyncio.run(main())

ROI Calculator for Domain Portfolios

Domain portfolio management requires tracking registration costs, renewal costs, and sales across many domains. Here is a portfolio P&L model that accounts for the full lifecycle:

from dataclasses import dataclass, field
from typing import List, Optional
from datetime import date


@dataclass
class DomainHolding:
    domain:         str
    reg_date:       date
    reg_cost_usd:   float
    annual_renewal: float
    status:         str = "active"   # active | sold | dropped
    sale_price_usd: Optional[float] = None
    sale_date:      Optional[date]  = None
    years_held:     int = 1


class DomainPortfolio:
    """
    Track P&L across a domain portfolio.
    Accounts for registration cost, annual renewals, and sale proceeds.
    """

    def __init__(self):
        self.holdings: List[DomainHolding] = []

    def add(self, holding: DomainHolding):
        self.holdings.append(holding)

    def total_cost(self) -> float:
        """Total invested: registration + renewals."""
        total = 0.0
        for h in self.holdings:
            reg_years = h.years_held
            total += h.reg_cost_usd + h.annual_renewal * (reg_years - 1)
        return total

    def total_revenue(self) -> float:
        """Total sales revenue from exited positions."""
        return sum(h.sale_price_usd or 0 for h in self.holdings if h.status == "sold")

    def realized_pnl(self) -> float:
        """Profit from sold domains."""
        pnl = 0.0
        for h in self.holdings:
            if h.status == "sold" and h.sale_price_usd:
                cost = h.reg_cost_usd + h.annual_renewal * (h.years_held - 1)
                pnl += h.sale_price_usd - cost
        return pnl

    def unrealized_cost(self) -> float:
        """Cost basis of currently held domains."""
        return sum(
            h.reg_cost_usd + h.annual_renewal * (h.years_held - 1)
            for h in self.holdings
            if h.status == "active"
        )

    def summary(self) -> dict:
        sold    = [h for h in self.holdings if h.status == "sold"]
        active  = [h for h in self.holdings if h.status == "active"]
        dropped = [h for h in self.holdings if h.status == "dropped"]

        avg_roi = 0.0
        if sold:
            rois = []
            for h in sold:
                cost = h.reg_cost_usd + h.annual_renewal * (h.years_held - 1)
                rois.append((h.sale_price_usd or 0) / cost if cost > 0 else 0)
            avg_roi = sum(rois) / len(rois)

        return {
            "total_domains":    len(self.holdings),
            "active":           len(active),
            "sold":             len(sold),
            "dropped":          len(dropped),
            "total_invested":   self.total_cost(),
            "total_revenue":    self.total_revenue(),
            "realized_pnl":     self.realized_pnl(),
            "unrealized_cost":  self.unrealized_cost(),
            "avg_roi_multiple": avg_roi,
            "win_rate":         len([h for h in sold if (h.sale_price_usd or 0) > h.reg_cost_usd]) / len(sold) if sold else 0,
        }


# Example portfolio
portfolio = DomainPortfolio()

portfolio.add(DomainHolding("agentlayer.ai",  date(2025, 1, 1), 89, 89, "sold",  4500, date(2025, 9, 1),  1))
portfolio.add(DomainHolding("mcphub.io",      date(2025, 2, 1), 29, 29, "sold",   850, date(2025, 7, 1),  1))
portfolio.add(DomainHolding("llmruntime.com", date(2025, 3, 1), 15, 15, "active", None, None,          1))
portfolio.add(DomainHolding("aiswarm.net",    date(2025, 4, 1), 12, 12, "dropped",None, None,          1))

s = portfolio.summary()
print(f"Portfolio: {s['total_domains']} domains")
print(f"Invested:  ${s['total_invested']:.2f}")
print(f"Revenue:   ${s['total_revenue']:.2f}")
print(f"P&L:       ${s['realized_pnl']:.2f}")
print(f"Avg ROI:   {s['avg_roi_multiple']:.1f}x")
print(f"Win rate:  {s['win_rate']:.0%}")
Sample output Portfolio: 4 domains | Invested: $145.00 | Revenue: $5350.00 | P&L: $5205.00 | Avg ROI: 24.8x | Win rate: 100%

Portfolio Management Principles

Domain speculation requires discipline to avoid over-accumulation and capital lock-up. Key principles for AI agent portfolios:

Purple Flea Domains + Escrow When selling a domain to another agent, use Purple Flea Escrow to protect both parties. The buyer's funds are locked in escrow; the domain transfers; escrow releases funds. No counterparty risk. 1% fee on the escrow value, 15% referral if you send agents to the service.

Register Domains Programmatically

Purple Flea's Domains API gives your agent full registration, transfer, and drop-catch capabilities. Combine with Faucet for startup funds and Escrow for safe P2P sales.

Domains API Docs → Get Free Funds