---
title: "How to Check if a Domain Name is Available to Register"
slug: "/resources/tutorial/how-to-check-if-a-domain-name-is-available-to-register"
description: "Check whether a domain name is free to register with the Domain Availability API; single lookups, suggestions, bulk lists & multi-TLD checks."
---

# How to Check if a Domain Name is Available to Register

Written By [Qasim](https://pk.linkedin.com/in/qasimleoo), WhoisFreaks Team Published: September 24, 2026, Last Updated: September 24, 2026

Before you can buy a domain, you need to know whether anyone already owns it. This tutorial shows you how to answer that with the WhoisFreaks Domain Availability API: one name, a name plus suggested alternatives, a whole list of names, or one name across a set of TLDs. It also covers the part most availability checks skip; what "available" does and does not promise.

> _You'll need an API key. If you don't have one yet,_ [_sign up and grab your key first_](https://whoisfreaks.com/resources/tutorial/getting-started-with-whoisfreaks-how-to-sign-up-and-get-your-api-key); _new accounts include 500 free credits, no card required._

## What "Available" Means Here

The API answers one question: is this exact domain currently registered by somebody? WhoisFreaks resolves that by cross-referencing real-time WHOIS data with live DNS resolution, so a domain sitting in redemption, pending deletion, or held by a registrar comes back as UNAVAILABLE rather than being wrongly reported as free.

That is a narrower question than "can I buy this today", and the gap matters:

| State | What the API says | Why |
| --- | --- | --- |
| Nobody has registered it | AVAILABLE | Genuinely registrable |
| Someone owns it | UNAVAILABLE | Registered |
| Expired, in redemption or pendingDelete | UNAVAILABLE | Not registrable yet; the previous owner can still recover it |
| Registry-reserved or premium-priced | UNAVAILABLE | Unregistered but not offered at standard price |

So, an AVAILABLE result is a green light. An UNAVAILABLE result is not a single fact; it can mean "taken", "recently expired" or "reserved", and the availability response does not distinguish between them. When that distinction matters, follow up with a [WHOIS lookup](https://whoisfreaks.com/resources/tutorial/how-to-use-the-whoisfreaks-api-for-domain-lookups) on the same name, which returns `domain_registered` and `domain_status` and tells you which of the three you're looking at. More on that in Step 5.

## Step 1: Get Your API Key

Sign in to the [WhoisFreaks dashboard](https://whoisfreaks.com/login) and open API Keys. Copy your primary key; it is the only credential this API needs, passed as the `apiKey` query parameter.

## Step 2: Check a Single Domain

Send a GET request with the domain you want to test:

```
curl "https://api.whoisfreaks.com/v2.0/domain/availability?apiKey=API_KEY&domain=whoisfreaks.com"
```

Replace `API_KEY` with your key and `whoisfreaks.com` with the name you're checking. Pass the registrable domain only; no `http://`, no `www.`, no trailing slash.

The response is a list of results, one entry per domain checked. For a single lookup it contains one:

```
{
  "domain_available_response": [
    {
      "domain": "whoisfreaks.com",
      "availability": "UNAVAILABLE"
    }
  ]
}
```

#### The two fields you'll read:

| Field | Meaning |
| --- | --- |
| domain | The domain that was checked, echoed back. Match on this rather than on array position. |
| availability | AVAILABLE or UNAVAILABLE, uppercase. Compare against the exact string. |

A standard availability lookup costs `1 credit`. Full costs are in the [credit usage documentation](https://whoisfreaks.com/documentation/credit-usage).

#### Parameters for this endpoint:

| Parameter | Required | Value |
| --- | --- | --- |
| apiKey | Yes | Your API key from the dashboard |
| domain | Yes | The domain to check, for example whoisfreaks.com |
| sug | No  | true to return suggested alternatives alongside the result |
| count | No  | How many suggestions to return, used with sug=true |

## Step 3: Get Suggestions When the Name Is Taken

Most of the time you're not checking a domain, you're hunting for one. Add sug=true and the API returns alternatives with their own availability, so a single call gives you a shortlist instead of a rejection:

```
curl "https://api.whoisfreaks.com/v2.0/domain/availability?apiKey=API_KEY&domain=whoisfreaks.com&sug=true"
```

Suggestions can run to 100 entries, which is more than a search box wants to render. Bound them with count:

```
curl "https://api.whoisfreaks.com/v2.0/domain/availability?apiKey=API_KEY&domain=whoisfreaks.com&sug=true&count=10"
```

```
{
  "domain_available_response": [
    {"domain": "whoisfreaks.xyz", "availability": "AVAILABLE"},
    {"domain": "whoisfreaks.net", "availability": "AVAILABLE"},
    {"domain": "whoisfreaks.club", "availability": "AVAILABLE"},
    {"domain": "whoisfreaks.com", "availability": "UNAVAILABLE"},
    {"domain": "whoisfreaks.info", "availability": "AVAILABLE"},
    {"domain": "whoisfreaks.loan", "availability": "AVAILABLE"},
    {"domain": "whoisfreaks.org", "availability": "AVAILABLE"},
    {"domain": "whoisfreaks.dev", "availability": "AVAILABLE"},
    {"domain": "whoisfreaks.top", "availability": "AVAILABLE"},
    {"domain": "whoisfreaks.biz", "availability": "AVAILABLE"}
  ]
}
```

Two things to note. The domain you asked about is included in the list, not returned separately; so find it by name, don't assume it's first or last. And suggestions are weighted toward high-registration-volume TLDs, which is why `.xyz`, `.club` and `.top` appear: the right bias for a checkout flow, the wrong one if you want specific TLDs. For that, use Step 4b.

## Step 4: Check a List of Domains in One Request

To test many names at once, POST a JSON body to the same endpoint. The `apiKey` stays in the query string:

```
curl "https://api.whoisfreaks.com/v1.0/domain/availability?apiKey=API_KEY" --header "Content-Type: application/json" --data '{"domainNames": ["google.com","whoisfreaks.jp"]}'
```

The list caps at **100 domains.** Send 101 and the API returns 413 with the message _"The requested list size is [GREATER_THAN_100] which exceeds the maximum list size of 100."_ Chunk longer lists into batches of 100 client-side. A full batch of 100 takes roughly 16 seconds to a minute to come back, so set your HTTP client's timeout accordingly; a 10-second default will abort a perfectly healthy request.

### Step 4b: Check One Name Across Several TLDs

When you want a specific set of extensions rather than the API's suggestions, keep domain in the query string and POST a TLD array:

```
curl "https://api.whoisfreaks.com/v1.0/domain/availability?apiKey=API_KEY&domain=whoisfreaks.com" --header "Content-Type: application/json" --data '{"tld": ["com","pk"]}'
```

This is the call for defensive registration checks; test the name you've settled on across the TLDs you actually care about, not the ones the suggestion engine likes. Write TLDs without a leading dot: `"com"`, not `".com"`.

## Step 5: Confirm Why a Domain Is Unavailable

`UNAVAILABLE` tells you not to bother, but not why. If you're tracking a name you want; a competitor's expiring domain, a brand term someone parked; run a WHOIS lookup on it and read two fields:

```
curl "https://api.whoisfreaks.com/v2.0/whois?apiKey=API_KEY&whois=live&domainName=example.com"
```

*   **`domain_registered`** is the string "yes" or "no", not a boolean. "no" on a domain the availability API called UNAVAILABLE is the signal that the name is unregistered but still blocked; reserved, premium, or between deletion stages.
*   **`domain_status`** carries the EPP status codes, returned lowercased and without EPP camelCase: you'll see **clienttransferprohibited**, not **clientTransferProhibited**, and **redemptionperiod** or **pendingdelete** rather than the camelCase forms. Lowercase your comparison strings or the match will silently fail.

A domain in **redemptionperiod** is not for sale, but it is on a clock; combine that with **expiry_date** in the same response and you know roughly when the name drops.

## Step 6: Handle the Failure Cases

Three things will happen to a script that runs this endpoint in a loop. Handle them before you ship:

*   **429 - rate limited:** The message is _"Please slow down. Your maximum request limit per minute is reached."_ Availability is a live endpoint, so the free tier's live limit applies: 500 credits at 10 requests per minute, and 5 requests per minute for bulk. Read `x-ratelimit-allowed-requests` and `x-ratelimit-remaining-requests` on every response, and sleep for `x-ratelimit-remaining-time` ;that header is in nanoseconds, so divide by 1,000,000,000 before passing it to sleep.
*   **413 - list too long:** Only from the bulk POST. Fix it by chunking, not by retrying.
*   **Bad input:** A malformed domain returns a 4xx. 4xx responses do not consume credits, so a validation bug costs you time but not balance. Validate the name client-side anyway.

## Summary

| Step | Action |
| --- | --- |
| 1   | Copy your API key from the dashboard |
| 2   | GET /v1.0/domain/availability with domain= for one name; 1 credit |
| 3   | Add sug=true, bound it with &count=10, to get alternatives |
| 4   | POST {"domainNames": [...]} for up to 100 names in one call |
| 4b  | POST {"tld": [...]} with domain= to check one name across chosen TLDs |
| 5   | Follow up UNAVAILABLE with a WHOIS lookup to learn why |
| 6   | Branch on 429 and 413; remember 4xx costs no credits |

One endpoint covers the whole job, from a single check in a signup form to a nightly sweep of a watchlist. If your question is the opposite one; which lookalike domains of your brand are already registered; see [How to Check Typosquat Domains of Your Brand](https://whoisfreaks.com/resources/tutorial/how-to-check-typosquat-domains-of-your-brand). Full parameter reference lives on the [Domain Availability API product page](https://whoisfreaks.com/products/domain-availability-api).

## Frequently Asked Questions

### How do I check if a domain name is available to register?

GET `https://api.whoisfreaks.com/v1.0/domain/availability` with your `apiKey` and the domain. The response holds a `domain_available_response` array with the domain name and an `availability` value of AVAILABLE or UNAVAILABLE. Costs 1 credit.

### Does the API tell me why a domain is unavailable?

No, the response is binary. It doesn't distinguish an actively registered domain from one in redemption, registry-reserved or premium-priced. Run a WHOIS lookup on the same name and read `domain_registered` and `domain_status` to find out which.

### Is domain availability checked against WHOIS or DNS?

Both. WhoisFreaks cross-references real-time WHOIS with live DNS resolution, which stops domains in redemption, pending deletion or on premium hold from being reported as free. That's why results are conservative rather than optimistic.

### How many domains can I check in one request?

Up to 100 per POST request; more returns a 413. Split longer lists into batches of 100 in your own code and allow roughly 16 seconds to a minute for a full batch to return.

### Can I get domain name suggestions from the same call?

Yes. Add `sug=true` to a single-domain request for up to 100 alternatives with their own availability, and `&count=10` to bound the list for a UI. Suggestions skew toward high-volume TLDs, which suits search widgets and checkout flows.

### How do I check one name across multiple TLDs?

Keep `domain=` in the query string and POST a body of `{"tld": ["com","pk"]}` with a `Content-Type: application/json` header. This checks that exact name against the TLDs you name, which is what you want for defensive registration. No leading dots.

### What happens if I hit the rate limit?

You get a 429. Availability is a live endpoint, so free accounts get 10 requests per minute on single lookups and 5 on bulk. Every response carries `x-ratelimit-remaining-requests` and `x-ratelimit-remaining-time`, in nanoseconds, so divide before you sleep on it.

### Do failed requests still cost credits?

No. 4xx responses cost a round trip but not balance, so a malformed domain or an oversized bulk list is free. Only successful lookups are charged at 1 credit for a standard check.

TIP

Match results by the domain field, never by array position. With sug=true the domain you asked about is returned inside the same list as the suggestions, and nothing guarantees its index. Code that reads `response[0]` works in testing and picks the wrong answer in production.

Compare availability against the exact uppercase strings AVAILABLE and UNAVAILABLE and treat anything else as unknown rather than as available. Defaulting to "available" on an unexpected value is how a checkout flow ends up selling a domain it cannot deliver.
