---
title: "Expired Domain API: Quick Start and Reference"
description: "REST API for vetted expired domains. Live list with filters, full reports, on-demand domain checks, alert rules and RDAP, DNS and Domain Rating lookups, as…"
url: https://hunter.domains/docs/api
language: en
---

# Expired domain API

The same lists and reports as the site, as JSON. Filter the daily hunt, read the full report of a domain, order a report for any domain and keep your alert rules in sync from your own code.

## Quick start

The base URL is `https://hunter.domains/api/v1`. Create a key on the [API page of your account](https://hunter.domains/account/api) 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`](https://hunter.domains/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](https://hunter.domains/account/api). 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/json` with a body on `POST` and `PATCH`.
- **One envelope.** A successful response is `{"data": …}`; lists add `{"meta": …}` with `total`, `page`, `per_page` and `pages`.
- **Pagination.** `page` starts at 1. `per_page` defaults 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) has `price_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 |
| --- | --- | --- |
| `domain` path · 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 |
| --- | --- | --- |
| `domain` path · required | string | The domain name. |
| `include` query | string | Send `content` to include the archived text (smaller pages: 10 by default, 20 at most). Values: `content`. |
| `page` query | integer | Page number, from 1. |
| `per_page` query | 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 |
| --- | --- | --- |
| `domain` path · 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 |
| --- | --- | --- |
| `domain` path · 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 |
| --- | --- | --- |
| `name` body · required | string | A label for the rule, up to 80 characters. |
| `frequency` body | 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_score` body | integer | Lowest Hunter score, 0–100. |
| `min_dr` body | integer | Lowest Domain Rating, 0–100. |
| `min_tf` body | integer | Lowest Trust Flow, 0–100. |
| `min_ref_domains` body | integer | Fewest referring domains. |
| `min_archive_years` body | integer | Fewest years in the archive, 0–30. |
| `max_price` body | integer | Highest price in USD. |
| `tlds` body | string[] | Extensions. |
| `listing_types` body | string[] | Listing types. Values: `bid`, `buy_now`, `pending_delete`, `auction`. |
| `topics` body | string[] | Niches. Values: `Arts`, `Business`, `Computers`, `Games`, `Health`, `Home`, `News`, `Recreation`, `Reference`, `Regional`, `Science`, `Shopping`, `Society`, `Sports`. |
| `langs` body | string[] | Languages of the old site. Values: `en`, `de`, `fr`, `es`, `it`, `nl`, `pt`, `tr`, `ru`, `sv`, `ja`. |
| `clean_only` body | boolean | Only domains without risk flags. |
| `keywords` body | string[] | Match only if the name or the old title contains one of these words. |
| `active` body | 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 |
| --- | --- | --- |
| `id` path · 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 |
| --- | --- | --- |
| `id` path · required | integer | The rule id. |
| `name` body | string | A label for the rule, up to 80 characters. |
| `frequency` body | 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_score` body | integer | Lowest Hunter score, 0–100. |
| `min_dr` body | integer | Lowest Domain Rating, 0–100. |
| `min_tf` body | integer | Lowest Trust Flow, 0–100. |
| `min_ref_domains` body | integer | Fewest referring domains. |
| `min_archive_years` body | integer | Fewest years in the archive, 0–30. |
| `max_price` body | integer | Highest price in USD. |
| `tlds` body | string[] | Extensions. |
| `listing_types` body | string[] | Listing types. Values: `bid`, `buy_now`, `pending_delete`, `auction`. |
| `topics` body | string[] | Niches. Values: `Arts`, `Business`, `Computers`, `Games`, `Health`, `Home`, `News`, `Recreation`, `Reference`, `Regional`, `Science`, `Shopping`, `Society`, `Sports`. |
| `langs` body | string[] | Languages of the old site. Values: `en`, `de`, `fr`, `es`, `it`, `nl`, `pt`, `tr`, `ru`, `sv`, `ja`. |
| `clean_only` body | boolean | Only domains without risk flags. |
| `keywords` body | string[] | Match only if the name or the old title contains one of these words. |
| `active` body | 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 |
| --- | --- | --- |
| `id` path · 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 |
| --- | --- | --- |
| `since` query | string | Only matches at or after this time (ISO 8601). |
| `limit` query | 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 |
| --- | --- | --- |
| `domain` body · 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 |
| --- | --- | --- |
| `page` query | integer | Page number, from 1. |
| `per_page` query | 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 |
| --- | --- | --- |
| `id` path · 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 |
| --- | --- | --- |
| `domain` query · 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 |
| --- | --- | --- |
| `domains` query · 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 |
| --- | --- | --- |
| `domains` query · 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 |
| --- | --- | --- |
| `host` query · 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 |
| --- | --- | --- |
| `url` body · required | string | An `https://` address on a public host. |
| `events` body | 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 |
| --- | --- | --- |
| `id` path · 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 |
| --- | --- | --- |
| `id` path · required | integer | The endpoint id. |
| `url` body | string | New address. |
| `events` body | string[] | New event list. Values: `alert.matched`, `domain.available`, `domain.ending_soon`, `check.completed`. |
| `active` body | 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 |
| --- | --- | --- |
| `id` path · 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 |
| --- | --- | --- |
| `id` path · 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 |
| --- | --- | --- |
| `id` path · 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](https://hunter.domains/docs/webhooks) 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

## Get a key, make your first request

A free account can create API keys and connect the MCP server to an assistant. No card needed.

[Create a free account](https://hunter.domains/register)

## Don't miss the next good domain.

Set your rule and leave the rest to us. You hear the moment a matching domain is found.

[Get started free](https://hunter.domains/register)
