GET /check/{domain} — check one domain
No API key, no account, no signup. Responses are JSON, CORS is open, and every endpoint is read-only — nothing here can register, buy or change anything.
Request
curl https://dotsweep.com/check/example.com
The domain goes in the path. Internationalised names are accepted and come back in their ASCII (Punycode) form, which is the canonical spelling and the only one two clients are guaranteed to agree on.
Response
{
"domain": "example.com",
"tld": "com",
"status": "available" | "taken" | "unknown",
"confidence": "certain" | "estimated",
"source": "rdap" | "dns" | "whois" | "cache",
"unused": true,
"price": {
"currency": "USD",
"registration": 11.08,
"renewal": 11.08,
"first_payment": 11.08,
"min_term_years": 2,
"promo_first_year": true,
"source": "Porkbun",
"note": "standard price; premium and reserved names cost more..."
},
"prices": [
{ "vendor": "dynadot", "currency": "USD", "registration": 3.48,
"renewal": 31.20, "first_payment": 3.48, "promo_first_year": true },
{ "vendor": "porkbun", "currency": "USD", "registration": 15.76,
"renewal": 31.20, "first_payment": 15.76, "quoted": true }
],
"policy": {
"tld": "eu",
"eligibility": "Registrant must be an EU/EEA citizen...",
"technical": "HTTPS only. The whole TLD is HSTS-preloaded...",
"min_term_years": 2,
"closed": true,
"closed_reason": "a .brand TLD reserved for its trademark owner (...)",
"source": "https://eurid.eu/...",
"verified": "2026-07-29"
},
"buy": [{ "id": "porkbun", "vendor": "Porkbun", "url": "...", "quoted": true }],
"offer": {
"kind": "listed" | "parked" | "expiring",
"venue": "Afternic",
"url": "https://www.afternic.com/domain/example.com",
"note": "listed on Afternic — price is on the listing, not in the registry"
}
}
Read confidence before status
certain means a registry answered. Act on it.
estimated means no registry answered and the verdict came from
DNS. A domain can be registered with no nameservers, so an estimated "available"
is a hint. note says why the answer stayed estimated.
An unreachable or rate-limited registry is never reported as available. That
is the whole reason to call this rather than whois: a raw WHOIS
reports a throttled registry as free, and a throttled registry is exactly what
you get when you check a lot of names at once.
Fields worth knowing about
| Field | What it means |
|---|---|
unused | Registered, but with no nameservers. Someone owns it and nothing is served from it, which is the taken domain most likely to be for sale. |
price | One registrar's, not a market rate. Exactly
one entry in buy carries quoted: true — that is the
vendor this figure belongs to. |
min_term_years | Where a registry will not sell a
single year. .ai is quoted at $82.70 everywhere and cannot be bought
for $82.70 by anyone, because the registry deals only in two-year terms. |
policy.closed | A .brand TLD, or one
whose ICANN agreement was terminated. Unregistered and unbuyable at once, so it
carries no price and no buy link. |
offer | Only filled by GET /whois/{domain}. A taken domain is caught by the DNS prefilter, so no registry record is fetched here and there is nothing to read a for-sale signal out of. |
buy[].url | The link to give a reader. It is an
absolute https://dotsweep.com/go/{vendor}/{domain} that forwards to that
registrar's search. There is no second URL: the hop is no-store,
no-referrer and noindex, so the name searched never
reaches the registrar in a referrer. |
When to use this instead of the batch
Use it for one domain, and for names somebody else has probably already checked. Each response is cached at the edge per URL, and a cache hit is served without reaching the Worker at all — so it costs nothing and is not rate-limited. Re-checking a popular name is effectively free.
For volume, POST /check carries ten domains per request against the same limit.
Errors
{ "error": { "code": "invalid_domain", "message": "...", "hint": "..." } }
Codes: invalid_domain, bad_body,
batch_too_large, rate_limited,
unknown_endpoint, method_not_allowed,
internal_error. The hint says what to do differently.
For anything other than rate_limited and internal_error,
repeating the same call fails the same way.
Rate limit
120 requests a minute per client, counted as requests rather than domains. Edge cache hits never reach the Worker and are not counted at all.
That rate is the whole quota. There is no daily or monthly ceiling, no credit balance and no trial that expires, so a job that stays under the rate can run as long as it needs to. Said plainly because an unstated limit gets read as a hidden one, and a caller who plans around a monthly cap is planning around nothing.
The other endpoints
POST /check— up to 10 domains per request, for volumeGET /whois/{domain}— registrar, dates, nameservers, and the for-sale signalGET /tlds— the full list, with price, term and eligibilityPOST /mcp— the same engine over Model Context Protocol