# Domain Availability Checker 🌐 (bulk .com/.io/.ai + WHOIS) (`tagadanar/domain-availability-checker`) Actor

Check which domains are free across .com, .io, .ai, .co, .net, .org, .app, .dev and more, in bulk. Taken domains come back with registrar, registration and expiry dates. Optional name variations and DNS check. Answers come straight from the registries, no API key.

- **URL**: https://apify.com/tagadanar/domain-availability-checker.md
- **Developed by:** [Tagada Data](https://apify.com/tagadanar) (community)
- **Categories:** Developer tools, Automation, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 domain checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Domain Availability Checker: bulk .com, .io, .ai and more, with registration and expiry dates

Paste your name ideas and get back, for each one, which domains are free across .com, .io, .ai, .co, .net, .org, .app, .dev or any other extension you list. Taken domains come with the registrar, the registration date, the expiry date, the registry status codes and the name servers, so you can see who owns a name, how old it is and whether it is about to drop.

Answers come straight from the registries (RDAP, with WHOIS where an extension has no RDAP, like .co). No API key, no login, no scraping of registrar storefronts.

$1 per 1,000 domains checked, platform usage included.

### What you get

One row per domain:

| Field | Description |
| --- | --- |
| `domain`, `name`, `tld` | The domain, its name part and its extension |
| `status` | `available`, `registered`, `reserved-or-premium` or `unknown` (see below) |
| `isAvailable` | `true`, `false`, or `null` when the answer is unknown |
| `registrar` | Registrar of record (taken domains) |
| `registeredAt`, `expiresAt`, `updatedAt` | Registration, expiry and last-change dates, ISO format |
| `daysUntilExpiry` | Days from the check to the expiry date |
| `domainStatus` | Registry status codes, for example `client transfer prohibited`, `redemption period`, `pending delete` |
| `nameservers` | Name servers of the domain |
| `rdapServer`, `checkedVia` | Which registry server answered, and whether by `rdap`, `whois` or `dns` |
| `variationOf` | The name idea this row is a variation of (only with variations on) |
| `dnsHasRecords` | Whether the domain has DNS delegation (only with the DNS check on) |
| `note` | A plain-words caveat when there is one |
| `capturedAt` | When the row was collected |

#### The four statuses

- **available**: the registry says the name is not registered. Registry lookups cannot see premium pricing or registrar-side reservations (common on .ai, .app and .dev), so the row carries a note: confirm the price at checkout.
- **registered**: the registry holds a record for it. Dates, registrar, status codes and name servers are filled in.
- **reserved-or-premium**: the registry itself lists the name as reserved or blocked.
- **unknown**: the registry could not give a trustworthy answer (it rate-limited the run, did not answer, or the extension has no public lookup). Unknown rows are never reported as available and are not charged. The run status says which extensions and why.

#### Example rows (real, from a run on 2026-10-16)

```json
{
  "domain": "sciences.io",
  "name": "sciences",
  "tld": "io",
  "status": "registered",
  "isAvailable": false,
  "registrar": "Spaceship, Inc.",
  "registeredAt": "2019-04-16T10:25:50.704Z",
  "expiresAt": "2027-04-16T10:25:50.704Z",
  "updatedAt": "2026-08-12T10:06:31.379Z",
  "daysUntilExpiry": 182,
  "domainStatus": ["client transfer prohibited"],
  "nameservers": ["ns1.afternic.com", "ns2.afternic.com"],
  "rdapServer": "https://rdap.identitydigital.services/rdap/",
  "checkedVia": "rdap",
  "variationOf": null,
  "note": null,
  "capturedAt": "2026-10-16T00:40:11.645Z"
}
```

```json
{
  "domain": "harasses.ai",
  "name": "harasses",
  "tld": "ai",
  "status": "available",
  "isAvailable": true,
  "registrar": null,
  "registeredAt": null,
  "expiresAt": null,
  "updatedAt": null,
  "daysUntilExpiry": null,
  "domainStatus": [],
  "nameservers": [],
  "rdapServer": "https://rdap.identitydigital.services/rdap/",
  "checkedVia": "rdap",
  "variationOf": null,
  "note": "Not registered at the registry. Premium or reserved-for-resale pricing is not visible to registry lookups, so confirm the price at checkout.",
  "capturedAt": "2026-10-16T00:40:11.338Z"
}
```

### Who uses this

- **Founders naming a product.** Drop in twenty ideas and see in one run which ones have a clean .com, .io or .ai.
- **Naming and branding agencies.** Check a client shortlist across every extension that matters, with the owner and expiry date of the taken ones.
- **Domain investors.** Spot names in `redemption period` or `pending delete`, sort taken names by `daysUntilExpiry`, and run big lists on a schedule.
- **Marketers and growth teams.** Validate campaign and microsite names in bulk before the brief goes out.

### Input

| Field | What it does |
| --- | --- |
| `names` | Name ideas, one per line. A bare name (`acme`) is checked on every extension; a full domain (`acme.io`) is checked as written. Spaces are closed up (`my cool app` becomes `mycoolapp`), URLs and `www.` are stripped, accented names become their international form |
| `tlds` | Extensions for the bare names, without the dot. Default: com, io, ai, co, net, org, app, dev. Any extension with a public registry lookup works |
| `generateVariations` | Also check `get`, `try`, `use` in front and `app`, `hq`, `labs`, `ly` after each name (7 extra names per idea, labelled in `variationOf`) |
| `includeDnsCheck` | Add `dnsHasRecords`, a second signal from DNS |
| `onlyAvailable` | Return only the available domains |

A run takes up to 3,000 domains. Larger lists: split them over several runs.

#### Three ideas on four extensions

```json
{
  "names": ["acme", "northwind", "blue fox labs"],
  "tlds": ["com", "io", "ai", "co"]
}
```

#### Find free variations only

```json
{
  "names": ["acme", "northwind"],
  "tlds": ["com", "io"],
  "generateVariations": true,
  "onlyAvailable": true
}
```

#### Check a list of exact domains

```json
{
  "names": ["acme.com", "acme.io", "getacme.ai"]
}
```

### Pricing

| Event | Price |
| --- | --- |
| Domain checked | $0.001 per domain, i.e. **$1 per 1,000 domains** |
| Run start | $0.001 per run |

Store discounts apply: Bronze $0.90, Silver $0.80, Gold $0.70 per 1,000 domains.

A domain is charged when it gets a definitive answer (available, registered or reserved). Unknown rows cost nothing beyond the run start. With `onlyAvailable` you are charged only for the available domains you receive. Platform usage is included.

A big check: 200 names on 8 extensions (1,600 domains) took 4.5 minutes in our test and costs $1.60 at the list price.

### How fast is it, and why can a big run take minutes

Registries limit how fast one address may ask: Google's .app and .dev allow about one lookup per second, Identity Digital's .io and .ai a few per second, Verisign's .com and .net and PIR's .org much more. The actor paces itself per registry, backs off when a registry says slow down, and opens extra routes when one address is limited. A mixed list of 8 extensions runs at roughly 6 domains per second overall; a list that is all .app and .dev is the slow case.

### FAQ

**Is "available" a guarantee I can register it?**
It means the registry holds no registration for the name. A domain can still be premium-priced or held back by a registrar, which registry lookups do not show. Always confirm at checkout.

**Why do .co and some other extensions say `checkedVia: whois`?**
They have no public RDAP service, so the actor asks the registry's WHOIS server instead. Same answer, older format.

**What does `unknown` mean?**
The registry did not give an answer this run could trust. Run those domains again later.

**Do you show who owns the domain?**
No. Registries hide personal data, so you get the registrar and dates, not the owner's name or contact details.

**Can I find domains about to expire?**
Yes: sort taken domains by `daysUntilExpiry`, and look for `redemption period` or `pending delete` in `domainStatus`.

**Does the DNS check change the availability answer?**
No. The registry answer is the answer; `dnsHasRecords` is an extra column. DNS is only used as the answer when an extension has no public registry lookup at all, and then only to prove a domain is taken.

### Related actors

- [Google Trends Scraper](https://apify.com/tagadanar/google-trends-scraper): check that people search for the name's topic before you register it.
- [Brand & News Monitor](https://apify.com/tagadanar/brand-news-monitor): watch the news for your new brand name.
- [Google AI Overview Tracker](https://apify.com/tagadanar/google-ai-overview-tracker): see whether your brand gets cited in Google's AI answers.
- [Threads Scraper](https://apify.com/tagadanar/threads-scraper): check who already talks about a name on Threads.

Keywords: domain availability checker, bulk domain checker, domain name search, whois lookup, RDAP, domain expiry checker, .io domain checker, .ai domain checker, domain name generator, domain investing.

# Changelog

This Actor's version history is a separate document: https://apify.com/tagadanar/domain-availability-checker/changelog.md

# Actor input Schema

## `names` (type: `array`):

One name idea per line (like acme) or a full domain (like acme.io). A bare name is checked on every extension below; a full domain is checked as written. Up to a few thousand domains per run.

## `tlds` (type: `array`):

Extensions to check each bare name on, without the dot. Default when empty: com, io, ai, co, net, org, app, dev. Any extension with a public registry lookup works (xyz, tech, fr, uk, ...).

## `generateVariations` (type: `boolean`):

Also checks get-, try- and use- in front of each name and app, hq, labs and ly after it (7 extra names per idea, each on every extension). Variations are labelled in the variationOf column.

## `includeDnsCheck` (type: `boolean`):

Adds a column saying whether the domain has DNS delegation (name servers). A second signal next to the registry answer; useful to spot parked or dropped names.

## `onlyAvailable` (type: `boolean`):

Leaves taken domains out of the dataset. You are only charged for rows delivered, so this also lowers the bill; domains the registry could not answer are listed in the run status instead.

## Actor input object example

```json
{
  "names": [
    "apify",
    "zzqx-unlikely-name-2026"
  ],
  "tlds": [
    "com",
    "io",
    "ai"
  ],
  "generateVariations": false,
  "includeDnsCheck": false,
  "onlyAvailable": false
}
```

# Actor output Schema

## `results` (type: `string`):

One item per domain in the default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "names": [
        "apify",
        "zzqx-unlikely-name-2026"
    ],
    "tlds": [
        "com",
        "io",
        "ai"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("tagadanar/domain-availability-checker").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "names": [
        "apify",
        "zzqx-unlikely-name-2026",
    ],
    "tlds": [
        "com",
        "io",
        "ai",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("tagadanar/domain-availability-checker").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "names": [
    "apify",
    "zzqx-unlikely-name-2026"
  ],
  "tlds": [
    "com",
    "io",
    "ai"
  ]
}' |
apify call tagadanar/domain-availability-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,tagadanar/domain-availability-checker"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/WEVCaWS3YuiGa4VrG/builds/7C9veasc3ULkd9qij/openapi.json
