close

Introduction

The CatchDoms API gives you programmatic access to expired and auction domains from 16 platforms (Dynadot, GoDaddy, DropCatch, Catched, Gname, SnapNames, UK Backorder, Subreg, WebExpire, Park.io, BloomUp, SEO.Domains, NameShift, Nicsell, Gnews Domains, Backorders Domains) plus 100k+ aged ccTLD domains at registration price (Authority plan only). Catalog refreshed daily.

All responses are JSON. The base URL for all endpoints is:

https://catchdoms.com/api

Data is refreshed daily. Auction bids update several times per day.

Authentication

All API requests require a Bearer token in the Authorization header.

To get your API key:

  1. Sign up or log in at catchdoms.com
  2. Go to the API Access page
  3. Create a new API token

API access requires a Pro subscription (468 EUR/year).

Example request header

Authorization: Bearer YOUR_API_KEY

Rate Limiting

Rate limit depends on your subscription: Pro: 15 requests per minute, Authority: 60 requests per minute, per token. Pro Lite trial users share the Pro rate limit but pagination is capped at the first 1,000 results per query.

Rate limit information is included in the response headers:

Header Description
X-RateLimit-Limit Your rate limit per minute
X-RateLimit-Remaining Requests remaining in current window

If you exceed the rate limit, you will receive a 429 Too Many Requests response. Wait 60 seconds before retrying.

Use per_page=100 to fetch more results per request and reduce API calls.

Endpoints

GET /api/domains

List domains

Returns a paginated list of domains. Accepts query parameters for filtering.

GET /api/domains/{id}

Get single domain

Returns the full domain object by its numeric ID.

GET /api/user

Get authenticated user

Returns the currently authenticated user's information.

Query Parameters

All parameters are optional. Add them to the query string of GET /api/domains.

Parameter Type Default Description
source string Filter by source platform. Use <code>regfree</code> for aged ccTLD domains available at registration price (requires Authority subscription).
dynadot, catched, dropcatch, godaddy, gname, snapnames, ukdroplists, subreg, webexpire, parkio, bloomup, seodomains, nameshift, nicsell, gnews-domains, backorders-domains, regfree
tld string Filter by TLD, with or without dot prefix. Comma-separated for multiple.
.com or .fr,.de,.it
score_min integer Minimum quality score (0-100). 50+ for good domains, 70+ for excellent.
age_min integer Minimum age in years, based on Wayback first snapshot
type string Filter by domain type
auction, closeout, backorder
has_bids boolean Only domains with active auction bids
has_backlinks boolean Only domains with referring domains (SEO value)
has_gmb boolean Only domains with a Google My Business listing
da_min integer Minimum Domain Authority (0-100)
rd_min integer Minimum number of referring domains
language string Filter by detected language code
EN, FR, DE, ES, etc.
contains string Keyword the domain name must contain (max 50 chars)
has_edu_gov boolean Only domains with EDU or GOV referring domains
tf_min integer Minimum Trust Flow score (0-100, from Majestic/SEObserver)
cf_min integer Minimum Citation Flow score (0-100, from Majestic/SEObserver)
categories string Comma-separated TTF topic categories (e.g., "Business,Health")
price_min number Minimum price or current bid amount (USD)
price_max number Maximum price or current bid amount (USD)
snapshots_min integer Minimum number of Wayback Machine snapshots
per_page integer 50 Results per page (1-100)
page integer 1 Page number for pagination

Response Fields

Each domain in the data array contains these fields.

Field Type Nullable Description
Identity
id integer No Unique domain identifier
name string No Full domain name
tld string No Top-level domain with dot prefix
source string No Source platform (dynadot, catched, dropcatch, godaddy, gname, snapnames, ukdroplists, subreg, webexpire, parkio, bloomup, seodomains, nameshift, nicsell, gnews-domains, backorders-domains, regfree โ€” regfree requires Authority)
type string No Domain type (auction, closeout, backorder)
auction_type string Yes Sub-type for DropCatch (Dropped, PreRelease, PrivateSeller) or GoDaddy (Bid, BuyNow)
Pricing
price float Yes Fixed price for closeouts, or starting price for auctions
max_bid float Yes Current highest bid for auction domains
effective_price float Yes The actual price to pay: max_bid if set, otherwise price. Use this field instead of checking both price and max_bid.
bids_count integer Yes Number of bids placed on the domain
auction_end_date string (ISO 8601) Yes When the auction ends (ISO 8601)
Scoring
estibot_appraisal float Yes Automated valuation estimate from the registrar
score integer Yes CatchDoms quality score (0-100), combining age, authority, backlinks, name quality, and TLD
is_spammy boolean No Whether the domain was flagged as spammy
History
age integer Yes Domain age in years (computed from wayback_first_date)
wayback_snapshots integer Yes Total number of Wayback Machine snapshots
wayback_first_date string (YYYY-MM-DD) Yes Date of earliest Wayback snapshot (YYYY-MM-DD)
wayback_last_date string (YYYY-MM-DD) Yes Date of latest Wayback snapshot (YYYY-MM-DD)
SEO Metrics
pagerank integer Yes Open PageRank score (0-10)
domain_authority integer Yes Domain Authority from DataForSEO (0-100)
backlinks_count integer Yes Total number of backlinks
referring_domains integer Yes Number of unique referring domains
trust_flow integer Yes Trust Flow from Majestic/SEObserver (0-100)
citation_flow integer Yes Citation Flow from Majestic/SEObserver (0-100)
ttf_topic string Yes Topical Trust Flow category (e.g., "Business/Marketing")
ref_domains_edu integer Yes Number of referring domains from .edu sites
ref_domains_gov integer Yes Number of referring domains from .gov sites
ref_domains_dofollow integer Yes Number of dofollow referring domains
SEO.Domains
seo_domains_category string Yes Primary category from seo.domains marketplace (seodomains source only, e.g., "Technology", "Finance")
seo_domains_subcategory string Yes Secondary/fine-grained category from seo.domains marketplace (seodomains source only)
indexed_pages integer Yes Number of pages indexed on Google (regfree: exact count from SERP; seodomains: 1 if indexed, 0 otherwise)
Traffic
monthly_visitors integer Yes Estimated monthly visitors (Dynadot and seodomains)
Language
language string Yes Detected language code (EN, FR, DE, etc.), from Wayback archived content
Google My Business
has_gmb boolean No Whether a GMB listing was found for this domain
gmb_name string Yes Business name from the GMB listing
gmb_category string Yes Business category from the GMB listing
gmb_address string Yes Business address from the GMB listing
WHOIS / RDAP
whois_registered_at string (ISO 8601) Yes Current registration date at the registry (ISO 8601). Reflects the current ownership cycle โ€” a recent value on an old domain signals it was dropped and re-registered.
whois_expires_at string (ISO 8601) Yes Domain expiry date at the registry (ISO 8601)
whois_last_changed_at string (ISO 8601) Yes Last time the registry record was modified (ISO 8601). Fresh timestamp = recent owner/DNS/registrar change.
whois_registrar string Yes Registrar holding the domain (e.g. "GoDaddy.com, LLC", "NameCheap, Inc.")
whois_status array<string> Yes Array of EPP status codes (e.g. ["clientTransferProhibited", "serverHold"])
whois_nameservers array<string> Yes Array of current nameservers (e.g. ["ns1.cloudflare.com", "ns2.cloudflare.com"])
whois_ns_category string Yes Classification derived from the nameservers: for_sale | parked | drop_catcher | active | registrar_default. null when nameservers are unknown or not classified.
whois_checked_at string (ISO 8601) Yes Last time WHOIS was fetched for this domain. null = never enriched; set with null fields = TLD has no public RDAP.
Links
purchase_url string Yes Direct link to bid/buy on the source platform
Timestamps
created_at string (ISO 8601) No When the domain was added to CatchDoms (ISO 8601)
updated_at string (ISO 8601) No When the domain was last updated (ISO 8601)

effective_price — The actual price to pay: max_bid if set, otherwise price. Use this field instead of checking both price and max_bid.

Pagination

All list endpoints return paginated results using Laravel's standard pagination format.

The meta object contains:

current_pageCurrent page number
last_pageLast page number
per_pageItems per page
totalTotal matching domains
fromFirst item index on this page
toLast item index on this page

The links object contains:

firstURL to the first page
lastURL to the last page
prevURL to the previous page (null on first page)
nextURL to the next page (null on last page)
{
  "data": [ ... ],
  "links": {
    "first": "https://catchdoms.com/api/domains?page=1",
    "last": "https://catchdoms.com/api/domains?page=68",
    "prev": null,
    "next": "https://catchdoms.com/api/domains?page=2"
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 68,
    "per_page": 50,
    "to": 50,
    "total": 3400
  }
}

Code Examples

Replace YOUR_API_KEY with your actual token.

# List domains with score >= 50 and backlinks
curl "https://catchdoms.com/api/domains?score_min=50&has_backlinks=1&per_page=10" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"

# Get a single domain by ID
curl "https://catchdoms.com/api/domains/12345" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"

# Filter by TLD and language
curl "https://catchdoms.com/api/domains?tld=.fr&language=FR&age_min=10" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"

# Filter by multiple TLDs
curl "https://catchdoms.com/api/domains?tld=.fr,.de,.it&score_min=50" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://catchdoms.com/api';

// List domains with filters
const params = new URLSearchParams({
  score_min: 50,
  has_backlinks: 1,
  per_page: 10
});

const response = await fetch(`${BASE_URL}/domains?${params}`, {
  headers: {
    'Authorization': `Bearer ${API_KEY}`,
    'Accept': 'application/json'
  }
});

const { data, meta } = await response.json();
console.log(`Found ${meta.total} domains`);

// Get a single domain
const domain = await fetch(`${BASE_URL}/domains/12345`, {
  headers: {
    'Authorization': `Bearer ${API_KEY}`,
    'Accept': 'application/json'
  }
}).then(r => r.json());
import requests

API_KEY = 'YOUR_API_KEY'
BASE_URL = 'https://catchdoms.com/api'

headers = {
    'Authorization': f'Bearer {API_KEY}',
    'Accept': 'application/json'
}

# List domains with filters
response = requests.get(f'{BASE_URL}/domains', headers=headers, params={
    'score_min': 50,
    'has_backlinks': 1,
    'language': 'FR',
    'per_page': 25
})
data = response.json()
print(f"Found {data['meta']['total']} domains")

for domain in data['data']:
    print(f"{domain['name']} - Score: {domain['score']} - Price: {domain['effective_price']}")

# Get a single domain
domain = requests.get(f'{BASE_URL}/domains/12345', headers=headers).json()

Errors

The API uses standard HTTP status codes. Error responses include a JSON body with a message field.

Code Meaning Description
200 Success Request completed successfully
401 Unauthorized Missing or invalid API token
403 Forbidden Valid token but no Pro subscription
404 Not Found Domain ID does not exist
422 Validation Error Invalid parameter value (e.g. score_min=abc)
429 Too Many Requests Rate limit exceeded. Wait 60 seconds.

Example error response

// 401 Unauthorized
{
  "message": "Unauthenticated."
}

// 429 Too Many Requests
{
  "message": "Too Many Attempts."
}

MCP Server

CatchDoms includes an MCP (Model Context Protocol) server for AI assistants like Claude Code, Cursor, and Windsurf.

Instead of writing API calls, you can ask natural language questions:

"Find .fr domains older than 10 years with backlinks"
"Show me GoDaddy auctions with score above 70"

Configuration

Add this to your MCP client config:

Claude Code / Cursor

{
  "mcpServers": {
    "catchdoms": {
      "type": "http",
      "url": "https://catchdoms.com/mcp/catchdoms",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}

Claude Desktop

{
  "mcpServers": {
    "catchdoms": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://catchdoms.com/mcp/catchdoms",
        "--header",
        "Authorization: Bearer YOUR_API_KEY"
      ]
    }
  }
}

Claude Code: ~/.claude.json | Cursor: MCP settings Claude Desktop requires Node.js.

Learn more about MCP integration

Troubleshooting

Getting HTML instead of JSON (Cloudflare captcha)

If your API calls return an HTML page with "Just a moment..." instead of JSON, your IP is being challenged by Cloudflare.

  • Disable your VPN or switch to a different VPN node/server
  • Try from a different IP address or network
  • Make sure you include the Accept: application/json header

403 Subscription Required

API access requires an active Pro subscription.

401 Unauthenticated

Your token is missing or invalid.

  • Make sure the header format is exactly: Authorization: Bearer YOUR_TOKEN (with "Bearer " prefix and a space)
  • Copy the full token including the number and pipe character (e.g. 42|abc...)
  • Tokens are shown only once at creation. If lost, revoke and create a new one.

MCP Server disconnected

If Claude Desktop shows "Server disconnected" for the CatchDoms MCP server:

  • Check that your token is still valid (create a new one if needed)
  • Disable VPN โ€” Cloudflare may block the connection
  • Restart Claude Desktop completely (Cmd+Q on Mac, not just close the window)
  • Verify your config file syntax in claude_desktop_config.json

Still having issues? Contact us at [email protected] with your error message and we'll help you debug.