Quick start
The base URL is https://hunter.domains/api/v1. Create a key on the API page of your account and send it with every request:
curl "https://hunter.domains/api/v1/domains?min_dr=30&tld=com,org" \
-H "Authorization: Bearer hd_…"
{
"data": [
{
"domain": "example.org",
"tld": "org",
"status": "listed",
"score": 78,
"verdict": "ok",
"flags": [],
"topic": "Home",
"language": "en",
"title": "Seasonal planting guides for small gardens",
"metrics": {
"domain_rating": 46,
"referring_domains": 412,
"archive_years": 17,
"archive_first_year": 2006,
"archive_last_year": 2025,
"trust_flow": 28,
"citation_flow": 31
},
"listing": {
"source": "godaddy",
"type": "bid",
"price_usd": 25,
"bids": 3,
"ends_at": "2026-10-09T17:30:00Z",
"url": "https://auctions.godaddy.com/trpItemListing.aspx?domain=example.org"
},
"found_at": "2026-10-06T16:42:10Z",
"open": true,
"detail": "full",
"report_url": "https://hunter.domains/domain/example.org"
}
],
"meta": {
"list": "live",
"total": 5,
"page": 1,
"per_page": 25,
"pages": 1,
"plan": "free",
"locked": 57,
"locked_note": "57 more matching domains are on the Pro list.",
"upgrade_url": "https://hunter.domains/pricing"
}
}
Three more calls cover most uses:
# The full report of a listed domain
curl "https://hunter.domains/api/v1/domains/example.org" -H "Authorization: Bearer hd_…"
# Dropped and still unregistered (Pro)
curl "https://hunter.domains/api/v1/domains/available" -H "Authorization: Bearer hd_…"
# A report for any domain, listed or not
curl -X POST "https://hunter.domains/api/v1/checks" -H "Authorization: Bearer hd_…" \
-H "Content-Type: application/json" -d '{"domain": "example.org"}'
A machine-readable description of every endpoint is at /api/v1/openapi.json (OpenAPI 3.1).
Authentication
Every request carries an API key in the Authorization header:
Authorization: Bearer hd_…
- Keys are created and deleted on the API page of your account. You can have up to 5; give each integration its own so you can revoke one without breaking the others.
- A key is shown once, when you create it. We store only a hash, so a lost key cannot be recovered; delete it and create a new one.
- A key acts as your account: it sees what your plan sees and can change your alert rules, watchlist and webhooks. Keep it on the server side. Do not put it in a web page, a mobile app or a public repository.
- The account's email address must be verified.
- All requests go over HTTPS.
Plans and limits
There is no separate API plan. A key returns what your account sees on the site.
| Free | Pro | |
|---|---|---|
| Requests | 30 a minute, 1,000 a day | 120 a minute, 20,000 a day |
| Live list | The day's 5 open domains | Every domain |
| Available now | Open domains only | Every domain |
| Detailed report and revival kit | Open domains | Every domain |
| Alert rules and webhooks | — | Yes |
| Lookups (RDAP, DNS, DR) | 200 domains an hour | 600 domains an hour |
Limits are per account: all your keys and MCP connections share them. Each response carries X-RateLimit-Limit and X-RateLimit-Remaining for the current minute. When you go over, the API answers 429 with a Retry-After header in seconds. The lookups have their own hourly quota, counted in domains, which they share with the free tools on the site.
On the free plan a list response contains only the domains you may see by name. meta.locked tells you how many more match your filters on the Pro list; it is left out when you search with q.
Requests and responses
- JSON in, JSON out. Send
Content-Type: application/jsonwith a body onPOSTandPATCH. - One envelope. A successful response is
{"data": …}; lists add{"meta": …}withtotal,page,per_pageandpages. - Pagination.
pagestarts at 1.per_pagedefaults to 25 and goes up to 100. - Lists in the query string are comma-separated:
tld=com,org. - Times are UTC in ISO 8601:
2026-10-09T17:30:00Z. Prices are in US dollars. - Missing values are
null, not zero. A domain with no price yet (pending delete) hasprice_usd: null. - New fields can appear at any time. Ignore the ones you do not know.
The domain object
Lists return this summary. The report endpoint returns the same object with more inside.
{
"domain": "example.org",
"tld": "org",
"status": "listed",
"score": 78,
"verdict": "ok",
"flags": [],
"topic": "Home",
"language": "en",
"title": "Seasonal planting guides for small gardens",
"metrics": {
"domain_rating": 46,
"referring_domains": 412,
"archive_years": 17,
"archive_first_year": 2006,
"archive_last_year": 2025,
"trust_flow": 28,
"citation_flow": 31
},
"listing": {
"source": "godaddy",
"type": "bid",
"price_usd": 25,
"bids": 3,
"ends_at": "2026-10-09T17:30:00Z",
"url": "https://auctions.godaddy.com/trpItemListing.aspx?domain=example.org"
},
"found_at": "2026-10-06T16:42:10Z",
"open": true,
"detail": "full",
"report_url": "https://hunter.domains/domain/example.org"
}
| Field | Meaning |
|---|---|
status |
listed, ending_soon (under 24 hours left), pending_delete, available (dropped and unregistered) or ended. |
score |
The Hunter score, 0–100. Domains under 45 are not listed. |
verdict |
ok, or risky when the history review found something worth a second look. |
flags |
Risk flags, shown rather than hidden: dr_inflated, parked, topic_change, lang_change, gap, trademark, not_indexed, anchor_foreign. An empty list means none. |
topic |
The niche: the top-level Majestic topic of the backlink profile, such as Health or Business. |
language, title |
The language and the title of the old site, read from the archive. |
metrics |
domain_rating (Ahrefs), referring_domains, the archive span, and with full detail trust_flow and citation_flow (Majestic). |
listing |
Where it is listed: source (godaddy, dropcatch, snapnames, sedo, dynadot, parkio, iis), type (bid, buy_now, auction, pending_delete), current price_usd, bids, ends_at and the url of the listing. For an available domain url leads to a registrar. |
found_at |
When the domain entered the list. |
open |
true if it is one of the day's open domains on the free plan. |
detail |
full when the response includes Trust Flow and the detailed report, basic otherwise. |
report_url |
The report page on the site. |
Errors
Errors use the HTTP status and one shape:
{
"error": {
"code": "plan_required",
"message": "This domain is on the Pro list.",
"upgrade_url": "https://hunter.domains/pricing",
"docs": "https://hunter.domains/docs/api#errors"
}
}
code is stable and meant for your program. message is for people and may be reworded.
| HTTP | code | Meaning |
|---|---|---|
| 401 | unauthenticated | The key is missing, mistyped or revoked. |
| 402 | no_checks_left | No domain check credits left. |
| 403 | email_unverified | The account’s email address is not verified yet. |
| 403 | plan_required | The domain or feature is part of Pro. The response carries upgrade_url. |
| 404 | not_found | No such resource, or the domain is not on the list. |
| 405 | method_not_allowed | The endpoint does not accept this HTTP method. |
| 409 | limit_reached | The plan’s limit for alert rules, watched domains or webhook endpoints is reached. |
| 422 | validation_failed | A parameter is missing or invalid. fields lists the messages by field. |
| 429 | rate_limited | Too many requests. Wait for the seconds in Retry-After. |
| 429 | lookup_quota_exceeded | The hourly quota of registry, DNS and DR lookups is used up. |
| 500 | server_error | Our fault. Safe to retry. |
Requests that fail with 429 or 5xx are safe to retry after a pause. Do not retry 4xx errors without changing the request.
Account and stats
Check what your key can do and how much of the daily scan made it to the list.
Your plan, limits and usage
GET /me
curl "https://hunter.domains/api/v1/me" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": {
"email": "you@example.com",
"plan": "pro",
"plan_renews_at": "2026-11-06T09:12:00Z",
"limits": {
"requests_per_minute": 120,
"requests_per_day": 20000,
"requests_today": 214,
"lookup_domains_per_hour": 600
},
"checks": {
"available": 27,
"from_plan_this_month": 27,
"welcome": 0,
"purchased": 0
},
"alerts": {
"used": 2,
"limit": 10
},
"watchlist": {
"used": 6,
"limit": null
},
"webhooks": {
"used": 1,
"limit": 3
}
}
}
Last scan and list sizes
GET /stats
curl "https://hunter.domains/api/v1/stats" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": {
"last_scan": {
"started_at": "2026-10-06T15:30:02Z",
"finished_at": "2026-10-06T17:48:40Z",
"scanned": 2656148,
"passed_authority_filter": 426
},
"live": {
"domains": 62,
"open_on_free_plan": 5,
"ending_within_24h": 14,
"average_score": 64.2,
"average_domain_rating": 36.1
},
"available_now": 9,
"archive": 310
}
}
Domains
Three lists share one shape: the live list (auctions and pending drops that have not ended), Available now (dropped, unregistered, re-checked against the registry every two hours) and the archive (everything that ended).
List filters
| Parameter | Type | Description |
|---|---|---|
q |
string | Search in the domain name and the old site title (up to 60 characters). |
min_score |
integer | Lowest Hunter score, 0–100. |
min_dr |
integer | Lowest Ahrefs Domain Rating, 0–100. |
min_tf |
integer | Lowest Majestic Trust Flow, 0–100. |
min_ref_domains |
integer | Fewest referring domains. |
min_archive_years |
integer | Fewest distinct years with Wayback captures, 0–30. |
max_price |
integer | Highest current price in USD. Domains without a price (pending delete) always pass. |
tld |
string | Extensions, comma-separated. |
type |
string | Listing types, comma-separated. Values: bid, buy_now, pending_delete, auction. |
topic |
string | Niches (the top Majestic topic), comma-separated. Values: Arts, Business, Computers, Games, Health, Home, News, Recreation, Reference, Regional, Science, Shopping, Society, Sports. |
lang |
string | Languages of the old site as two-letter codes, comma-separated. |
clean |
boolean | Only domains with verdict ok and no risk flags. |
since |
string | Only domains found at or after this time (ISO 8601). Use it to fetch what is new since your last call. |
ending_within_hours |
integer | Only listings that end within this many hours, 1–720. |
sort |
string | Default score (ended on the archive). Values: score, dr, ending, newest, price, ended. |
page |
integer | Page number, from 1. |
per_page |
integer | Items per page: 1–100, default 25. |
The live list
GET /domains
Domains whose auction or drop has not ended yet, best score first. On the free plan the response holds the day’s open domains and meta.locked tells you how many more match on Pro.
Parameters: List filters.
curl "https://hunter.domains/api/v1/domains?min_dr=30&tld=com,org" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": [
{
"domain": "example.org",
"tld": "org",
"status": "listed",
"score": 78,
"verdict": "ok",
"flags": [],
"topic": "Home",
"language": "en",
"title": "Seasonal planting guides for small gardens",
"metrics": {
"domain_rating": 46,
"referring_domains": 412,
"archive_years": 17,
"archive_first_year": 2006,
"archive_last_year": 2025,
"trust_flow": 28,
"citation_flow": 31
},
"listing": {
"source": "godaddy",
"type": "bid",
"price_usd": 25,
"bids": 3,
"ends_at": "2026-10-09T17:30:00Z",
"url": "https://auctions.godaddy.com/trpItemListing.aspx?domain=example.org"
},
"found_at": "2026-10-06T16:42:10Z",
"open": true,
"detail": "full",
"report_url": "https://hunter.domains/domain/example.org"
}
],
"meta": {
"list": "live",
"total": 5,
"page": 1,
"per_page": 25,
"pages": 1,
"plan": "free",
"locked": 57,
"locked_note": "57 more matching domains are on the Pro list.",
"upgrade_url": "https://hunter.domains/pricing"
}
}
Available now
GET /domains/available
Listed domains that dropped and that nobody registered. No auction: the price is a normal registration fee. A Pro list; the free plan only sees a domain here if it was one of its open domains.
Parameters: List filters.
curl "https://hunter.domains/api/v1/domains/available" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": [
{
"domain": "example.org",
"tld": "org",
"status": "available",
"score": 78,
"verdict": "ok",
"flags": [],
"topic": "Home",
"language": "en",
"title": "Seasonal planting guides for small gardens",
"metrics": {
"domain_rating": 46,
"referring_domains": 412,
"archive_years": 17,
"archive_first_year": 2006,
"archive_last_year": 2025,
"trust_flow": 28,
"citation_flow": 31
},
"listing": {
"source": "dropcatch",
"type": "pending_delete",
"price_usd": null,
"bids": 0,
"ends_at": "2026-10-04T18:00:00Z",
"url": "https://www.spaceship.com/domain-search/?query=example.org"
},
"found_at": "2026-10-06T16:42:10Z",
"open": true,
"detail": "full",
"report_url": "https://hunter.domains/domain/example.org"
}
],
"meta": {
"list": "available",
"total": 5,
"page": 1,
"per_page": 25,
"pages": 1,
"plan": "free",
"locked": 57,
"locked_note": "57 more matching domains are on the Pro list.",
"upgrade_url": "https://hunter.domains/pricing"
}
}
The archive
GET /domains/archive
Every listed domain whose auction or drop has ended, most recent first. Open to every plan.
Parameters: List filters.
curl "https://hunter.domains/api/v1/domains/archive" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": [
{
"domain": "example.org",
"tld": "org",
"status": "ended",
"score": 78,
"verdict": "ok",
"flags": [],
"topic": "Home",
"language": "en",
"title": "Seasonal planting guides for small gardens",
"metrics": {
"domain_rating": 46,
"referring_domains": 412,
"archive_years": 17,
"archive_first_year": 2006,
"archive_last_year": 2025,
"trust_flow": 28,
"citation_flow": 31
},
"listing": {
"source": "godaddy",
"type": "bid",
"price_usd": 25,
"bids": 3,
"ends_at": "2026-10-09T17:30:00Z",
"url": "https://auctions.godaddy.com/trpItemListing.aspx?domain=example.org"
},
"found_at": "2026-10-06T16:42:10Z",
"open": true,
"detail": "full",
"report_url": "https://hunter.domains/domain/example.org"
}
],
"meta": {
"list": "archive",
"total": 5,
"page": 1,
"per_page": 25,
"pages": 1,
"plan": "free",
"locked": 57,
"locked_note": "57 more matching domains are on the Pro list.",
"upgrade_url": "https://hunter.domains/pricing"
}
}
The full report of a listed domain
GET /domains/{domain}
Everything on the report page: metrics, score breakdown, top referring domains, anchors, topical Trust Flow, risk checks and, once the listing has ended, the registration status. detail is full for the day’s open domains and for every domain on Pro, basic otherwise. Returns 404 for a domain that is not on the list; use a domain check for those.
| Parameter | Type | Description |
|---|---|---|
domainpath · required |
string | The domain name. |
curl "https://hunter.domains/api/v1/domains/example.org" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": {
"domain": "example.org",
"tld": "org",
"status": "listed",
"score": 78,
"verdict": "ok",
"flags": [],
"topic": "Home",
"language": "en",
"title": "Seasonal planting guides for small gardens",
"metrics": {
"domain_rating": 46,
"referring_domains": 412,
"archive_years": 17,
"archive_first_year": 2006,
"archive_last_year": 2025,
"trust_flow": 28,
"citation_flow": 31,
"tf_cf_ratio": 0.9,
"backlinks": 9840,
"semrush_authority_score": 21,
"moz_domain_authority": 33,
"open_pagerank": 4.1,
"google_indexed_pages": 10,
"archived_urls": 1260
},
"listing": {
"source": "godaddy",
"type": "bid",
"price_usd": 25,
"bids": 3,
"ends_at": "2026-10-09T17:30:00Z",
"url": "https://auctions.godaddy.com/trpItemListing.aspx?domain=example.org"
},
"found_at": "2026-10-06T16:42:10Z",
"open": true,
"detail": "full",
"report_url": "https://hunter.domains/domain/example.org",
"score_breakdown": {
"ahrefs_dr": 0.92,
"trust_flow": 0.7,
"ref_domains": 0.87,
"semrush_as": 0.7,
"open_pagerank": 0.41,
"history": 1,
"age": 1,
"price": 0.8,
"penalty": 0
},
"top_referring_domains": [
"rhs.org.uk",
"gardenersworld.com",
"extension.umn.edu"
],
"anchors": {
"top": [
{
"text": "seasonal planting guide",
"referring_domains": 38
},
{
"text": "example.org",
"referring_domains": 27
}
],
"spam_share": 0
},
"topical_trust_flow": [
{
"topic": "Home/Gardening",
"trust_flow": 27
},
{
"topic": "Recreation/Outdoors",
"trust_flow": 14
}
],
"risk_checks": [
{
"flag": "dr_inflated",
"label": "Inflated DR",
"result": "clean",
"severity": "risk",
"note": "DR is in line with the number of referring domains"
},
{
"flag": "topic_change",
"label": "Topic changed",
"result": "clean",
"severity": "info",
"note": "Site topic is the same throughout the archive"
}
],
"wayback_url": "https://web.archive.org/web/*/example.org",
"registration": null,
"rank_on_hunt_day": 4,
"revival_kit": {
"pages": 38,
"url": "https://hunter.domains/api/v1/domains/example.org/pages"
}
}
}
The revival kit: old URLs and archived text
GET /domains/{domain}/pages
The most archived pages of the old site, with capture counts and Wayback links. Rebuild these paths (or 301 them) and the old backlinks keep working. Add include=content to get the archived text of each page as Markdown.
| Parameter | Type | Description |
|---|---|---|
domainpath · required |
string | The domain name. |
includequery |
string | Send content to include the archived text (smaller pages: 10 by default, 20 at most). Values: content. |
pagequery |
integer | Page number, from 1. |
per_pagequery |
integer | Items per page: 1–100, default 50. |
curl "https://hunter.domains/api/v1/domains/example.org/pages" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": [
{
"path": "/guides/spring-planting",
"url": "http://example.org/guides/spring-planting",
"captures": 64,
"last_capture": "2025-03-18",
"title": "Spring planting calendar",
"words": 1180,
"wayback_url": "https://web.archive.org/web/20250318101500/http://example.org/guides/spring-planting",
"has_content": true
}
],
"meta": {
"domain": "example.org",
"total": 38,
"page": 1,
"per_page": 50,
"pages": 1
}
}
Watchlist
Domains you follow. On Pro a watched domain triggers a reminder before its auction ends and a notice if it drops unregistered.
Domains you watch
GET /watchlist
curl "https://hunter.domains/api/v1/watchlist" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": [
{
"domain": "example.org",
"tld": "org",
"status": "listed",
"score": 78,
"verdict": "ok",
"flags": [],
"topic": "Home",
"language": "en",
"title": "Seasonal planting guides for small gardens",
"metrics": {
"domain_rating": 46,
"referring_domains": 412,
"archive_years": 17,
"archive_first_year": 2006,
"archive_last_year": 2025,
"trust_flow": 28,
"citation_flow": 31
},
"listing": {
"source": "godaddy",
"type": "bid",
"price_usd": 25,
"bids": 3,
"ends_at": "2026-10-09T17:30:00Z",
"url": "https://auctions.godaddy.com/trpItemListing.aspx?domain=example.org"
},
"found_at": "2026-10-06T16:42:10Z",
"open": true,
"detail": "full",
"report_url": "https://hunter.domains/domain/example.org"
}
]
}
Watch a domain
PUT /watchlist/{domain}
Idempotent. The free plan watches up to 3 domains.
| Parameter | Type | Description |
|---|---|---|
domainpath · required |
string | The domain name. |
curl -X PUT "https://hunter.domains/api/v1/watchlist/example.org" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": {
"domain": "example.org",
"tld": "org",
"status": "listed",
"score": 78,
"verdict": "ok",
"flags": [],
"topic": "Home",
"language": "en",
"title": "Seasonal planting guides for small gardens",
"metrics": {
"domain_rating": 46,
"referring_domains": 412,
"archive_years": 17,
"archive_first_year": 2006,
"archive_last_year": 2025,
"trust_flow": 28,
"citation_flow": 31
},
"listing": {
"source": "godaddy",
"type": "bid",
"price_usd": 25,
"bids": 3,
"ends_at": "2026-10-09T17:30:00Z",
"url": "https://auctions.godaddy.com/trpItemListing.aspx?domain=example.org"
},
"found_at": "2026-10-06T16:42:10Z",
"open": true,
"detail": "full",
"report_url": "https://hunter.domains/domain/example.org"
}
}
Stop watching a domain
DELETE /watchlist/{domain}
| Parameter | Type | Description |
|---|---|---|
domainpath · required |
string | The domain name. |
curl -X DELETE "https://hunter.domains/api/v1/watchlist/example.org" \
-H "Authorization: Bearer hd_…"
204 · No response body.
Alert rules
A rule describes the domains you want. Every newly listed domain is matched against your rules; a match sends an email and the alert.matched webhook.
Your alert rules
GET /alerts
curl "https://hunter.domains/api/v1/alerts" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": [
{
"id": 12,
"name": "Health, DR 30+",
"active": true,
"frequency": "instant",
"min_score": 60,
"min_dr": 30,
"min_tf": null,
"min_ref_domains": null,
"min_archive_years": 5,
"max_price": 150,
"tlds": [
"com",
"org"
],
"listing_types": [],
"topics": [
"Health"
],
"langs": [
"en"
],
"clean_only": true,
"keywords": [],
"match_count": 7,
"last_matched_at": "2026-10-05T16:51:30Z",
"created_at": "2026-10-03T10:20:00Z"
}
]
}
Create an alert rule Pro
POST /alerts
Up to 10 rules. Leave a field out (or send 0) for “no limit”.
| Field | Type | Description |
|---|---|---|
namebody · required |
string | A label for the rule, up to 80 characters. |
frequencybody |
string | instant emails each match as it is found; daily saves matches for the daily digest. Default instant. Webhooks always fire at once. Values: instant, daily. |
min_scorebody |
integer | Lowest Hunter score, 0–100. |
min_drbody |
integer | Lowest Domain Rating, 0–100. |
min_tfbody |
integer | Lowest Trust Flow, 0–100. |
min_ref_domainsbody |
integer | Fewest referring domains. |
min_archive_yearsbody |
integer | Fewest years in the archive, 0–30. |
max_pricebody |
integer | Highest price in USD. |
tldsbody |
string[] | Extensions. |
listing_typesbody |
string[] | Listing types. Values: bid, buy_now, pending_delete, auction. |
topicsbody |
string[] | Niches. Values: Arts, Business, Computers, Games, Health, Home, News, Recreation, Reference, Regional, Science, Shopping, Society, Sports. |
langsbody |
string[] | Languages of the old site. Values: en, de, fr, es, it, nl, pt, tr, ru, sv, ja. |
clean_onlybody |
boolean | Only domains without risk flags. |
keywordsbody |
string[] | Match only if the name or the old title contains one of these words. |
activebody |
boolean | Whether the rule is on. Default true. |
curl -X POST "https://hunter.domains/api/v1/alerts" \
-H "Authorization: Bearer hd_…" \
-H "Content-Type: application/json" \
-d '{"name":"Health, DR 30+","min_score":60,"min_dr":30,"max_price":150,"tlds":["com","org"],"topics":["Health"],"clean_only":true}'
Response · 201
{
"data": {
"id": 12,
"name": "Health, DR 30+",
"active": true,
"frequency": "instant",
"min_score": 60,
"min_dr": 30,
"min_tf": null,
"min_ref_domains": null,
"min_archive_years": 5,
"max_price": 150,
"tlds": [
"com",
"org"
],
"listing_types": [],
"topics": [
"Health"
],
"langs": [
"en"
],
"clean_only": true,
"keywords": [],
"match_count": 7,
"last_matched_at": "2026-10-05T16:51:30Z",
"created_at": "2026-10-03T10:20:00Z"
}
}
One alert rule
GET /alerts/{id}
| Parameter | Type | Description |
|---|---|---|
idpath · required |
integer | The rule id. |
curl "https://hunter.domains/api/v1/alerts/12" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": {
"id": 12,
"name": "Health, DR 30+",
"active": true,
"frequency": "instant",
"min_score": 60,
"min_dr": 30,
"min_tf": null,
"min_ref_domains": null,
"min_archive_years": 5,
"max_price": 150,
"tlds": [
"com",
"org"
],
"listing_types": [],
"topics": [
"Health"
],
"langs": [
"en"
],
"clean_only": true,
"keywords": [],
"match_count": 7,
"last_matched_at": "2026-10-05T16:51:30Z",
"created_at": "2026-10-03T10:20:00Z"
}
}
Change an alert rule
PATCH /alerts/{id}
Send only the fields you want to change. {"active": false} pauses the rule.
| Parameter | Type | Description |
|---|---|---|
idpath · required |
integer | The rule id. |
namebody |
string | A label for the rule, up to 80 characters. |
frequencybody |
string | instant emails each match as it is found; daily saves matches for the daily digest. Default instant. Webhooks always fire at once. Values: instant, daily. |
min_scorebody |
integer | Lowest Hunter score, 0–100. |
min_drbody |
integer | Lowest Domain Rating, 0–100. |
min_tfbody |
integer | Lowest Trust Flow, 0–100. |
min_ref_domainsbody |
integer | Fewest referring domains. |
min_archive_yearsbody |
integer | Fewest years in the archive, 0–30. |
max_pricebody |
integer | Highest price in USD. |
tldsbody |
string[] | Extensions. |
listing_typesbody |
string[] | Listing types. Values: bid, buy_now, pending_delete, auction. |
topicsbody |
string[] | Niches. Values: Arts, Business, Computers, Games, Health, Home, News, Recreation, Reference, Regional, Science, Shopping, Society, Sports. |
langsbody |
string[] | Languages of the old site. Values: en, de, fr, es, it, nl, pt, tr, ru, sv, ja. |
clean_onlybody |
boolean | Only domains without risk flags. |
keywordsbody |
string[] | Match only if the name or the old title contains one of these words. |
activebody |
boolean | Whether the rule is on. Default true. |
curl -X PATCH "https://hunter.domains/api/v1/alerts/12" \
-H "Authorization: Bearer hd_…" \
-H "Content-Type: application/json" \
-d '{"name":"Health, DR 30+","min_score":60,"min_dr":30,"max_price":150,"tlds":["com","org"],"topics":["Health"],"clean_only":true}'
Response · 200
{
"data": {
"id": 12,
"name": "Health, DR 30+",
"active": true,
"frequency": "instant",
"min_score": 60,
"min_dr": 30,
"min_tf": null,
"min_ref_domains": null,
"min_archive_years": 5,
"max_price": 150,
"tlds": [
"com",
"org"
],
"listing_types": [],
"topics": [
"Health"
],
"langs": [
"en"
],
"clean_only": true,
"keywords": [],
"match_count": 7,
"last_matched_at": "2026-10-05T16:51:30Z",
"created_at": "2026-10-03T10:20:00Z"
}
}
Delete an alert rule
DELETE /alerts/{id}
| Parameter | Type | Description |
|---|---|---|
idpath · required |
integer | The rule id. |
curl -X DELETE "https://hunter.domains/api/v1/alerts/12" \
-H "Authorization: Bearer hd_…"
204 · No response body.
Domains that matched your rules
GET /alerts/matches
Newest match first. Poll it with since if you cannot receive webhooks.
| Parameter | Type | Description |
|---|---|---|
sincequery |
string | Only matches at or after this time (ISO 8601). |
limitquery |
integer | How many to return: 1–100, default 50. |
curl "https://hunter.domains/api/v1/alerts/matches" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": [
{
"matched_at": "2026-10-06T16:44:02Z",
"alert": {
"id": 12,
"name": "Health, DR 30+"
},
"domain": {
"domain": "example.org",
"tld": "org",
"status": "listed",
"score": 78,
"verdict": "ok",
"flags": [],
"topic": "Home",
"language": "en",
"title": "Seasonal planting guides for small gardens",
"metrics": {
"domain_rating": 46,
"referring_domains": 412,
"archive_years": 17,
"archive_first_year": 2006,
"archive_last_year": 2025,
"trust_flow": 28,
"citation_flow": 31
},
"listing": {
"source": "godaddy",
"type": "bid",
"price_usd": 25,
"bids": 3,
"ends_at": "2026-10-09T17:30:00Z",
"url": "https://auctions.godaddy.com/trpItemListing.aspx?domain=example.org"
},
"found_at": "2026-10-06T16:42:10Z",
"open": true,
"detail": "full",
"report_url": "https://hunter.domains/domain/example.org"
}
}
]
}
Domain checks
Order the full report for any domain, listed or not. A check reads the Wayback history, so it runs in a queue and usually finishes within two minutes. Each new check uses one credit; asking again for the same domain within 7 days returns the existing report for free.
Order a report for any domain
POST /checks
Returns 202 with a queued check, or 200 with the existing check if this domain was checked in the last 7 days. Poll GET /checks/{id} every few seconds, or subscribe to the check.completed webhook. Returns 402 when no credits are left.
| Field | Type | Description |
|---|---|---|
domainbody · required |
string | The domain to check. A URL or a subdomain is reduced to the registered domain. |
curl -X POST "https://hunter.domains/api/v1/checks" \
-H "Authorization: Bearer hd_…" \
-H "Content-Type: application/json" \
-d '{"domain":"example.org"}'
Response · 202
{
"data": {
"id": "01k6x2f0q8m3r7t9v4b5n6c8dz",
"domain": "example.org",
"status": "queued",
"created_at": "2026-10-06T17:02:11Z",
"finished_at": null,
"score": null,
"verdict": null,
"report_url": "https://hunter.domains/domain-checker/report/01k6x2f0q8m3r7t9v4b5n6c8dz",
"queue_position": 1
}
}
Your checks
GET /checks
| Parameter | Type | Description |
|---|---|---|
pagequery |
integer | Page number, from 1. |
per_pagequery |
integer | Items per page: 1–50, default 25. |
curl "https://hunter.domains/api/v1/checks" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": [
{
"id": "01k6x2f0q8m3r7t9v4b5n6c8dz",
"domain": "example.org",
"status": "done",
"created_at": "2026-10-06T17:02:11Z",
"finished_at": "2026-10-06T17:03:24Z",
"score": 78,
"verdict": "ok",
"report_url": "https://hunter.domains/domain-checker/report/01k6x2f0q8m3r7t9v4b5n6c8dz"
}
],
"meta": {
"total": 4,
"page": 1,
"per_page": 25,
"pages": 1
}
}
A check and, when done, its report
GET /checks/{id}
status is queued, running, done or failed. A failed check does not use a credit. would_list tells you whether the same domain would have passed our daily vetting; reject_reasons says why not.
| Parameter | Type | Description |
|---|---|---|
idpath · required |
string | The check id. |
curl "https://hunter.domains/api/v1/checks/01k6x2f0q8m3r7t9v4b5n6c8dz" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": {
"id": "01k6x2f0q8m3r7t9v4b5n6c8dz",
"domain": "example.org",
"status": "done",
"created_at": "2026-10-06T17:02:11Z",
"finished_at": "2026-10-06T17:03:24Z",
"score": 78,
"verdict": "ok",
"report_url": "https://hunter.domains/domain-checker/report/01k6x2f0q8m3r7t9v4b5n6c8dz",
"would_list": true,
"reject_reasons": [],
"report": {
"…": "same shape as GET /domains/{domain}"
},
"registration": {
"state": "registered",
"registrar": "Example Registrar, LLC",
"registered_at": "2006-04-11T09:00:00Z",
"expires_at": "2027-04-11T09:00:00Z",
"statuses": [
"client transfer prohibited"
]
}
}
}
Lookups
Live registry (RDAP), DNS and Domain Rating lookups. They do not use check credits; they share the hourly quota of the free tools on the site.
Registration record and drop estimate
GET /tools/whois
Read live from the registry through RDAP: state, registrar, dates, status codes, name servers and, for generic extensions, the window in which the domain will drop.
| Parameter | Type | Description |
|---|---|---|
domainquery · required |
string | The domain name. |
curl "https://hunter.domains/api/v1/tools/whois?domain=example.org" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": {
"domain": "example.org",
"state": "registered",
"registrar": "Example Registrar, LLC",
"registrar_iana_id": "146",
"registered_at": "2006-04-11T09:00:00Z",
"expires_at": "2027-04-11T09:00:00Z",
"updated_at": "2026-03-02T08:14:00Z",
"statuses": [
"client transfer prohibited"
],
"nameservers": [
"ns1.example.net",
"ns2.example.net"
],
"dnssec": false,
"drop_estimate": {
"stage": "active",
"earliest": "2027-05-16",
"latest": "2027-06-30",
"exact": false,
"drop_hour_utc": null
}
}
}
Bulk availability
GET /tools/availability
state is available, registered, dropping (in redemption or pending delete) or unknown (the registry has no RDAP service or did not answer). Up to 20 domains a request on the free plan, 50 on Pro.
| Parameter | Type | Description |
|---|---|---|
domainsquery · required |
string | Comma-separated domain names. |
curl "https://hunter.domains/api/v1/tools/availability?domains=example.org,example.com" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": [
{
"domain": "example.org",
"state": "registered",
"registrar": "Example Registrar, LLC",
"registrar_iana_id": "146",
"registered_at": "2006-04-11T09:00:00Z",
"expires_at": "2027-04-11T09:00:00Z",
"updated_at": "2026-03-02T08:14:00Z",
"statuses": [
"client transfer prohibited"
],
"nameservers": [
"ns1.example.net",
"ns2.example.net"
],
"dnssec": false
}
]
}
Ahrefs Domain Rating
GET /tools/domain-rating
Up to 10 domains a request on the free plan, 25 on Pro. Results are cached for 7 days. A row can carry error: "busy_retry_later" when the upstream limit is reached.
| Parameter | Type | Description |
|---|---|---|
domainsquery · required |
string | Comma-separated domain names. |
curl "https://hunter.domains/api/v1/tools/domain-rating?domains=example.org,example.com" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": [
{
"domain": "example.org",
"domain_rating": 46,
"error": null
}
]
}
DNS records
GET /tools/dns
A, AAAA, CNAME, MX, NS, TXT, SOA and CAA records, plus mail, SPF, DMARC and parking signals.
| Parameter | Type | Description |
|---|---|---|
hostquery · required |
string | A domain or subdomain. |
curl "https://hunter.domains/api/v1/tools/dns?host=example.org" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": {
"host": "example.org",
"records": {
"A": [
{
"value": "93.184.215.14",
"ttl": 300,
"extra": null
}
],
"MX": [
{
"value": "mail.example.org",
"ttl": 3600,
"extra": "10"
}
],
"NS": [
{
"value": "a.iana-servers.net",
"ttl": 86400,
"extra": null
}
]
},
"has_mail": true,
"spf": true,
"dmarc": false,
"parked_at": null
}
}
Webhook endpoints
Manage where events are delivered. Payloads, signatures and retries are described on the webhooks page.
Your webhook endpoints
GET /webhooks
curl "https://hunter.domains/api/v1/webhooks" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": [
{
"id": 3,
"url": "https://hooks.example.com/hunter",
"events": [
"alert.matched",
"domain.available"
],
"active": true,
"disabled_at": null,
"consecutive_failures": 0,
"last_delivered_at": "2026-10-06T16:44:03Z",
"created_at": "2026-10-03T10:25:00Z"
}
]
}
Add a webhook endpoint Pro
POST /webhooks
Up to 3 endpoints. The signing secret is returned once, in this response only; store it.
| Field | Type | Description |
|---|---|---|
urlbody · required |
string | An https:// address on a public host. |
eventsbody |
string[] | Events to deliver. Default: all. Values: alert.matched, domain.available, domain.ending_soon, check.completed. |
curl -X POST "https://hunter.domains/api/v1/webhooks" \
-H "Authorization: Bearer hd_…" \
-H "Content-Type: application/json" \
-d '{"url":"https://hooks.example.com/hunter","events":["alert.matched","domain.available"]}'
Response · 201
{
"data": {
"id": 3,
"url": "https://hooks.example.com/hunter",
"events": [
"alert.matched",
"domain.available"
],
"active": true,
"disabled_at": null,
"consecutive_failures": 0,
"last_delivered_at": "2026-10-06T16:44:03Z",
"created_at": "2026-10-03T10:25:00Z",
"secret": "whsec_3Qd…"
}
}
One webhook endpoint
GET /webhooks/{id}
| Parameter | Type | Description |
|---|---|---|
idpath · required |
integer | The endpoint id. |
curl "https://hunter.domains/api/v1/webhooks/12" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": {
"id": 3,
"url": "https://hooks.example.com/hunter",
"events": [
"alert.matched",
"domain.available"
],
"active": true,
"disabled_at": null,
"consecutive_failures": 0,
"last_delivered_at": "2026-10-06T16:44:03Z",
"created_at": "2026-10-03T10:25:00Z"
}
}
Change or re-enable an endpoint
PATCH /webhooks/{id}
An endpoint that failed 15 deliveries in a row is switched off; send {"active": true} to switch it back on.
| Parameter | Type | Description |
|---|---|---|
idpath · required |
integer | The endpoint id. |
urlbody |
string | New address. |
eventsbody |
string[] | New event list. Values: alert.matched, domain.available, domain.ending_soon, check.completed. |
activebody |
boolean | Pause or resume deliveries. |
curl -X PATCH "https://hunter.domains/api/v1/webhooks/12" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": {
"id": 3,
"url": "https://hooks.example.com/hunter",
"events": [
"alert.matched",
"domain.available"
],
"active": true,
"disabled_at": null,
"consecutive_failures": 0,
"last_delivered_at": "2026-10-06T16:44:03Z",
"created_at": "2026-10-03T10:25:00Z"
}
}
Remove an endpoint
DELETE /webhooks/{id}
| Parameter | Type | Description |
|---|---|---|
idpath · required |
integer | The endpoint id. |
curl -X DELETE "https://hunter.domains/api/v1/webhooks/12" \
-H "Authorization: Bearer hd_…"
204 · No response body.
Send a test event
POST /webhooks/{id}/test
Queues a ping event to the endpoint, whatever it is subscribed to.
| Parameter | Type | Description |
|---|---|---|
idpath · required |
integer | The endpoint id. |
curl -X POST "https://hunter.domains/api/v1/webhooks/12/test" \
-H "Authorization: Bearer hd_…"
Response · 202
{
"data": {
"id": "evt_01k6x2f0q8m3r7t9v4b5n6c8dz",
"event": "ping",
"status": "pending",
"attempts": 0,
"response_code": null,
"error": null,
"created_at": "2026-10-06T16:44:02Z",
"delivered_at": null
}
}
Recent deliveries
GET /webhooks/{id}/deliveries
The last 50 deliveries with their status and the response code of the latest attempt. Kept for 14 days.
| Parameter | Type | Description |
|---|---|---|
idpath · required |
integer | The endpoint id. |
curl "https://hunter.domains/api/v1/webhooks/12/deliveries" \
-H "Authorization: Bearer hd_…"
Response · 200
{
"data": [
{
"id": "evt_01k6x2f0q8m3r7t9v4b5n6c8dz",
"event": "alert.matched",
"status": "delivered",
"attempts": 1,
"response_code": 200,
"error": null,
"created_at": "2026-10-06T16:44:02Z",
"delivered_at": "2026-10-06T16:44:03Z"
}
]
}
Recipes
Fetch what is new since the last run. Store the time of your last call and pass it as since:
curl "https://hunter.domains/api/v1/domains?since=2026-10-06T00:00:00Z&sort=newest" \
-H "Authorization: Bearer hd_…"
Watch for cheap drops in your niche. Combine the list filters:
curl "https://hunter.domains/api/v1/domains/available?topic=Health&lang=en&min_dr=25&clean=true" \
-H "Authorization: Bearer hd_…"
Check a domain before you bid. Order the check, then poll until status is done:
curl -X POST "https://hunter.domains/api/v1/checks" -H "Authorization: Bearer hd_…" \
-H "Content-Type: application/json" -d '{"domain": "example.org"}'
curl "https://hunter.domains/api/v1/checks/01k6x2f0q8m3r7t9v4b5n6c8dz" -H "Authorization: Bearer hd_…"
A check usually takes one to two minutes. Poll every 10 seconds at most, or let the check.completed webhook tell you.
Skip polling altogether. Create an alert rule that describes what you want and add a webhook endpoint. Matches arrive at your endpoint as they are found.
Versioning
The version is in the path: /api/v1. Within a version we only make changes that do not break a working client: new endpoints, new optional parameters and new fields in responses. A change that would break clients ships as a new version; before the old one is retired we email every account that has an active key.
Frequently asked questions
Is there an API for expired domains?
Yes. hunter.domains has a REST API that returns its daily list of vetted expired domains as JSON, with the score, Domain Rating, Trust Flow, referring domains, archive history and risk flags of each one. It also returns domains that dropped and are still unregistered, and a full report for any domain you name.
How much does the API cost?
Nothing extra. It is part of your plan: the free plan gets the day's 5 open domains, the archive and the lookups; Pro ($9.99 a month) gets the full list, Available now, alert rules and webhooks.
Can I get every domain you scanned?
No. The API returns the domains that passed the vetting, which is a few dozen a day, not the two million that were scanned. The value is in what was removed.
Can I check a domain that is not on your list?
Yes, with POST /checks. It runs the same history, spam, blacklist and authority review on any domain and uses one check credit. For a quick look without a credit, GET /tools/whois, /tools/availability and /tools/domain-rating are free.
Do you offer a WHOIS or availability API?
GET /tools/whois returns the registration record of a domain read live from its registry through RDAP, with a drop-date estimate. GET /tools/availability checks up to 20 domains in one request on the free plan and 50 on Pro. Both work for extensions whose registry offers RDAP, which covers .com, .net, .org and most others, but not .com.tr, .se, .nu, .it or .es.
Can I call the API from a browser?
Technically yes, but do not. A key in front-end code can be read by anyone who opens the page. Call the API from your server and pass the result on.
Updated: 6 October 2026