How we check availability

Registration and purchasability are genuinely different facts.

Everything below is generated from the live configuration this site runs on, and every claim comes with the command to check it yourself.

The short version

A registry can tell you, definitively, whether a domain has a registration record. That is the question RDAP answers, and we ask the registry itself rather than a middleman.

It cannot tell you whether you can buy it. A domain with no registration record can still be priced as a premium name, reserved by the registry, or simply not carried by your registrar. Those are different facts from different systems, and anything that shows you one number for both is guessing about at least one of them.

Check our work
Build the example around

Typing a domain sets the extension from it, because that is how our checker resolves one — expert.dev is looked up under .dev.

Step 1 — find the registry. IANA publishes the map of every top-level domain to its RDAP server at data.iana.org/rdap/dns.json. We cache it and re-read it daily. For .dev it resolves to:

https://pubapi.registry.google/rdap/

Step 2 — ask it about a domain. The HTTP status code is the answer: 200 means a registration record exists, 404 means it does not.

# The domain you picked -- expected: HTTP 404
curl -sI -H 'Accept: application/rdap+json' \
  https://pubapi.registry.google/rdap/domain/h1xnzwjttcjz18.dev | head -1

# The control: nic.dev, which we expect to answer HTTP 200
curl -sI -H 'Accept: application/rdap+json' \
  https://pubapi.registry.google/rdap/domain/nic.dev | head -1

Both halves matter. A server that answered 200 to everything would report every domain as taken, and a check that only ever asks about one domain cannot tell that apart from a working one. We run the pair.

h1xnzwjttcjz18.dev was generated for this page load and will be different next time. Fourteen random characters is about 1020 possibilities against a DNS of well under a billion names — if it ever comes back 200, something far more interesting than a documentation bug has happened.

The same request in PHP, Python, Ruby, C# and JavaScript

No API key, no account, no registration. RDAP is an open standard and these are public endpoints. Every sample below queries h1xnzwjttcjz18.dev — change that one string to ask about anything else.

$ch = curl_init('https://pubapi.registry.google/rdap/domain/h1xnzwjttcjz18.dev');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Accept: application/rdap+json'],
]);
curl_exec($ch);
$code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

// 200 = registered, 404 = no registration record
echo $code === 404 ? 'no registration record' : 'registered';
import urllib.request, urllib.error

url = 'https://pubapi.registry.google/rdap/domain/h1xnzwjttcjz18.dev'
req = urllib.request.Request(url, headers={'Accept': 'application/rdap+json'})

# The 404 arrives as an exception, not a return value -- urllib raises on
# any 4xx, so the "available" answer has to be caught rather than read.
try:
    with urllib.request.urlopen(req) as r:
        print('registered', r.status)
except urllib.error.HTTPError as e:
    print('no registration record' if e.code == 404 else f'unexpected {e.code}')
require 'net/http'
require 'uri'

uri = URI('https://pubapi.registry.google/rdap/domain/h1xnzwjttcjz18.dev')
req = Net::HTTP::Get.new(uri, 'Accept' => 'application/rdap+json')
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }

# Net::HTTP returns the status as a STRING, not an integer -- '404', not 404.
puts res.code == '404' ? 'no registration record' : 'registered'
using System;
using System.Net;
using System.Net.Http;

using var http = new HttpClient();
http.DefaultRequestHeaders.Add("Accept", "application/rdap+json");

var res = await http.GetAsync("https://pubapi.registry.google/rdap/domain/h1xnzwjttcjz18.dev");

// Do NOT call EnsureSuccessStatusCode() here. HttpClient throws only on
// transport failures, so the 404 arrives as an ordinary response -- and
// that 404 IS the answer you came for.
Console.WriteLine(res.StatusCode == HttpStatusCode.NotFound
    ? "no registration record"
    : "registered");
const res = await fetch(
  'https://pubapi.registry.google/rdap/domain/h1xnzwjttcjz18.dev',
  { headers: { Accept: 'application/rdap+json' } }
);

// fetch() does not reject on 4xx, so no try/catch is needed -- but note that
// from a BROWSER this is a cross-origin request and most registry RDAP
// servers do not send CORS headers. Run it server-side (Node, Deno, Bun).
console.log(res.status === 404 ? 'no registration record' : 'registered');

One courtesy if you build on this: registries publish these endpoints as a compliance obligation, not as a high-throughput API, and several attach terms asking you not to hit them with high-volume automated processes. Honour Retry-After on a 429, keep concurrency per registry in the low single digits, and cache what you get.

Where WHOIS fits, and why it goes last

There are three ways to ask, and we use them in a fixed order.

Tier The question it actually answers
DNS Is this name pointed at nameservers? One UDP packet, fast enough to run across hundreds of thousands of candidates — and blind in one specific way, below.
RDAP Does the registry hold a registration record? Structured JSON, defined status codes, no parsing guesswork. Used whenever the extension has one.
WHOIS The same question as RDAP, asked the way we asked it in 1982. Last resort, and confirm-only.

WHOIS runs only when RDAP structurally cannot answer — that is, when the extension has no RDAP server in the IANA bootstrap file at all. It is not a fallback for RDAP having a bad day. If a registry's RDAP server is slow or throwing errors we back off and retry it; we do not quietly switch to a weaker source and keep the same confidence badge.

It is also confirm-only. WHOIS never produces a verdict here on its own — it confirms or contradicts a DNS “available”, which is why you will not find it in the list of check methods further down. That list is what you can choose; WHOIS is something the checker reaches for on your behalf.

Why it is last: RDAP answers with a status code. WHOIS answers with free text and no schema — RFC 3912 defines the transport (open TCP port 43, send a line, read until the server hangs up) and says nothing whatsoever about what comes back. So “is this domain free?” degrades into matching phrases like No match, NOT FOUND or Status: free, which differ per registry and can change without notice. That is a fine last resort and a terrible primary source: a parser that guesses wrong reports a registered domain as available, which is the one error that costs you money.

Second-level extensions always land here. IANA bootstraps .uk, not .co.uk, so for extensions like .co.uk or .com.au RDAP has nothing to route to and every answer falls through by construction.

For .dev — the extension in the example above — RDAP answers, so WHOIS is never consulted.
What the confidence badge means

Shown next to every Available result. These descriptions are read from the same code that assigns the grade, so they cannot drift.

Grade What it means
High High confidence — the registry itself was asked and reported no registration for this domain. Note this says nothing about PRICE: a domain can be unregistered and still be sold as a premium name for far above the base rate.
Medium Medium confidence — DNS says available and a second opinion was requested, but the registry errored, rate-limited, or answered unclearly. The DNS result stands unverified.
Low Low confidence — this rests on DNS alone, and no registry check was ever attempted. DNS cannot tell an unregistered domain from a registered-but-parked one, so treat this as a lead, not a fact. Re-check with RDAP before acting on it.
What we cannot tell you
  • Price. A domain with no registration record can still be a premium name. We have measured one at $500.20 that RDAP correctly reported as unregistered.
  • Registry reservations. Some names are held back and never released. They have no registration record either, so they look identical to a free domain over RDAP.
  • Your registrar's inventory. Registrars choose what to sell. One declining to sell you a name is not evidence that it is registered — we have seen a registrar report "registered already" for a domain the registry itself says has no record.

This is the boundary of what a registration lookup can establish, not a gap in our checking. The definitive answer on price and purchasability is the checkout page of a registrar that carries the extension.

What DNS cannot see

A DNS check is one UDP packet and it is fast enough to run across hundreds of thousands of candidates. It answers a different question: is this name delegated to nameservers?

A domain someone registered this morning and never pointed anywhere is absent from DNS and looks free. That blind spot is the one that costs money — it is the failure where you go to buy a domain and find it taken. Only a registry lookup sees registration itself, which is why DNS-only answers are graded Low and expire quickly.

How long we trust an answer

Live values from this site's configuration.

Answer forRe-checked after
.com 24 hours
.io 12 hours
.dev 48 hours
DNS-only "available" 1 hours

Separately, an Available result older than 7 days is downgraded a confidence grade. That is a different question from the cache lifetime above — one asks "is it worth spending a lookup to re-check this?", the other asks "should you trust this enough to go spend money?"

Coverage

We track 591 extensions. 502 of them can be routed to a registry RDAP server via the IANA bootstrap file; the remaining 89 are answered by DNS alone, backed up by WHOIS where one is reachable, and carry the lower confidence grade that implies.

Check methods you can choose:

  • dns — DNS Check
  • rdap — RDAP (recommended)