# Domain Availability Checker: Bulk, RDAP, Name Ideas (`charlesmarkette/domain-availability-checker-bulk-name-ideas`) Actor

Check which domain names are free to register, in bulk, with no API key. Paste names or generate ideas from keywords × TLDs (.com, .io, .ai, .app…) with prefixes and suffixes. Official registry RDAP with WHOIS fallback, plus registrar and expiry for taken names.

- **URL**: https://apify.com/charlesmarkette/domain-availability-checker-bulk-name-ideas.md
- **Developed by:** [Charles Markette](https://apify.com/charlesmarkette) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 checked domains

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** tells you which domain names are **free to register**, in bulk, with **no API key** and no registrar account. Paste a list of domains, or type a few **keywords** and it generates the name ideas for you: every keyword × every TLD (.com, .io, .ai, .co.uk…), with optional **prefixes** (get, try, my), **suffixes** (app, hq, labs) and **hyphenated variants**. Each name comes back as one row: `available: true` or `false`, how it was checked, and for taken names the registrar and expiry date if you want them.

### How it checks

1. **DNS first (fast).** If the name has nameservers in DNS, it's registered: `available: false`, `method: "dns"`. Most taken names are settled here quickly, without querying the registry.
2. **Then the registry.** Names not in DNS are checked against the registry's official **RDAP** service (found through IANA's RDAP list). "Not found" means `available: true`; a record means `available: false` (registered names without nameservers are caught here). For TLDs without RDAP, it asks the registry's **WHOIS** server instead.
3. **If neither answers clearly**, the row has `available: null` and an `error` saying why. These rows are free.

It sends at most 3 requests at a time to any one registry and retries when a server is busy, honouring `Retry-After`.

### Use cases

- **Brand and startup naming:** type 10 name ideas and get every free .com, .io, .ai and .app version in one run, plus get-/-hq style variants.
- **Domain investors:** check a list of thousands of names you're watching, and keep only the free ones with *Output only available names*.
- **Agencies:** check names for several clients at once, then export the free ones to a Google Sheet for the client to pick from.
- **Enriching a list of company names:** point it at a dataset of companies (from a scraper or a CSV). Items with a website get that domain checked; set **Name fields** (for example `companyName`) and items with only a name get domain ideas generated from the name ("Blue Fox Ltd" → bluefox.com, bluefox.io…).

### How to use it

1. Add **Domains to check**, and/or **Keywords** with the **TLDs** to try (default: com, net, org, io, co, app, dev, ai). Add **Prefixes**, **Suffixes** or **Hyphenated variants** if you want more ideas.
2. Optionally pick a **Dataset to enrich**. Set **Domain fields** if yours aren't named domain, website, url or email, and **Name fields** (for example `companyName`) to generate ideas from company names.
3. Run it. Turn on **Output only available names** for a short list, or **Registrar and dates for taken names** to see who holds the taken ones and when they expire.

Keywords are cleaned into valid domain labels: lowercase, spaces and punctuation removed ("Blue Fox!" → bluefox), apostrophes dropped ("Joe's" → joes), accented names converted to punycode ("café" → xn--caf-dma). Labels longer than 63 characters are skipped. **Max generated names** (default 500) caps how many names the keywords can produce.

**Input example**

```json
{
  "keywords": ["blue fox", "quiet otter"],
  "tlds": ["com", "io", "ai", "co.uk"],
  "prefixes": ["get"],
  "suffixes": ["hq"],
  "hyphenVariants": true,
  "onlyAvailable": true
}
```

**Output example**

```json
{
  "domain": "getbluefox.io",
  "label": "getbluefox",
  "tld": "io",
  "available": true,
  "method": "rdap",
  "premiumOrReservedPossible": true,
  "registrar": null,
  "createdAt": null,
  "expiresAt": null,
  "daysUntilExpiry": null,
  "sourceKeyword": "blue fox",
  "sourcePrefix": "get",
  "sourceSuffix": null,
  "domainInput": null,
  "checkedAt": "2026-10-15T09:12:44Z",
  "error": null
}
```

A taken name checked with *Registrar and dates for taken names* turned on looks like `"available": false, "method": "dns", "registrar": "Example Registrar, Inc.", "createdAt": "2009-06-02T17:14:10Z", "expiresAt": "2035-06-02T17:14:10Z", "daysUntilExpiry": 3152`. `domainInput` is the original text for names from your list or dataset. `method` is `dns`, `rdap` or `whois`. A run summary (counts of available, taken, unknown and invalid names) is saved as `OUTPUT` in the key-value store.

### How much does it cost?

Pay per event: **$0.0023 per checked domain**, plus **$0.005 per run start**. Apify platform usage is included.

**Apify Store discounts:** the price above is for Apify's Free plan. Paid plans pay less per 1,000 checked domains: $2.00 on Starter, $1.56 on Scale, $1.20 on Business. The "from" price at the top of the Store page is the Business price.

You pay only for rows with a definite answer (`available` true or false). These are free: rows with `available: null` (the registry couldn't be reached or didn't answer clearly), rows for input that isn't a domain, repeats skipped by *Check each domain once*, and names left out by *Output only available names*.

**Worked examples:**

*Examples use the Free-plan rate. Where an example doesn't add it, each run also has its run-start charge, counted per GB of Actor memory (minimum one; one at the default memory); Apify Proxy (where used) is billed separately.*

- 20 keywords × 8 TLDs = 160 names: 160 × $0.0023 + $0.005 = **$0.373**.
- A list of 5,000 names: 5,000 × $0.0023 + $0.005 = **$11.505**.

If you set a maximum cost per run, the Actor stops cleanly at that limit.

### FAQ and limits

#### Does "available" mean I can buy it at the normal price?

Not always. `available: true` means the registry has no registration for the name. Some registries sell certain names at **premium prices**, and some names are **reserved** by the registry or blocked by registrars, even though they aren't registered. `premiumOrReservedPossible: true` marks available names in TLDs known to have premium pricing (for example .io, .ai, .co, .app, .dev, .xyz). Other TLDs can have reserved names too. **Always confirm the price at your registrar's checkout.**

#### Can a name be taken between my check and my purchase?

Yes. The result is correct at `checkedAt`. Popular names can be registered by someone else minutes later.

#### What does "available": null mean?

The name couldn't be confirmed: the registry was busy or unreachable, the TLD publishes neither RDAP nor WHOIS, or its WHOIS reply didn't say clearly. See `error`, and re-run those rows later. They are free.

#### Why is a taken name shown without a registrar?

By default, names found in DNS are reported as taken without asking the registry (faster, and polite to registries). Turn on *Registrar and dates for taken names* to fetch the registrar, creation and expiry dates.

#### Which TLDs are supported?

Any public TLD or second-level ending (co.uk, com.au…) that publishes RDAP or WHOIS. Some country-code registries publish little or rate-limit heavily, so expect more `null` rows there. Subdomains in your list are reduced to the registrable domain (`blog.example.com` → `example.com`).

#### Does it buy or reserve domains?

No. It only checks. It never registers anything and doesn't collect domain owners' personal data.

### Related Actors

| Actor | Use it to |
|---|---|
| [Domain WHOIS & DNS Lookup](https://apify.com/charlesmarkette/domain-whois-dns-lookup-bulk-rdap) | Get full registration, DNS and email-setup data for taken domains. |
| [Merge & Deduplicate Datasets](https://apify.com/charlesmarkette/merge-deduplicate-datasets-only-new-items) | Keep only new names between scheduled runs. |
| [Google Sheets Import & Export](https://apify.com/charlesmarkette/google-sheets-sync) | Send the free names to a Google Sheet to share with a client or team. |
| [Email & Slack Report](https://apify.com/charlesmarkette/send-email-report-slack-discord-teams-telegram-alerts) | Send the list of free names by email, Slack, Discord, Teams or Telegram after each run. |
| [Dataset Filter & Transform](https://apify.com/charlesmarkette/dataset-filter-transform-rename-flatten-fields) | Keep only the available names, or drop columns before sharing the list. |
| [Bulk URL Status Checker](https://apify.com/charlesmarkette/bulk-url-status-checker-redirects-ssl) | Check that the taken domains have live websites, and follow their redirects. |

RDAP bootstrap data: [IANA](https://data.iana.org/rdap/dns.json). Domain parsing: [tldextract](https://github.com/john-kurkowski/tldextract) with the Public Suffix List.

# Actor input Schema

## `domains` (type: `array`):

One per line. Domains (bluefox.com), website URLs (https://www.bluefox.com/page) or email addresses (hi@bluefox.com) all work: the registrable domain is taken from each. Bare words without a TLD go in Keywords below.

## `keywords` (type: `array`):

Words or brand ideas to turn into domain names, one per line ("blue fox", "Café Luna"). Each keyword is combined with every TLD below. Spaces and punctuation are removed ("blue fox" becomes bluefox); accented names become punycode (xn--…).

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

Endings to try for each keyword, without the dot. Multi-part endings such as co.uk work.

## `prefixes` (type: `array`):

Optional words to put before each keyword, for example get, try, my (gives getbluefox.com).

## `suffixes` (type: `array`):

Optional words to put after each keyword, for example app, hq, labs (gives bluefoxhq.com).

## `hyphenVariants` (type: `boolean`):

For keywords with several words, also try the hyphenated form ("blue fox" gives both bluefox and blue-fox).

## `maxGenerated` (type: `integer`):

Cap on the names generated from Keywords (and from each dataset item's name). Names are generated keyword by keyword, so later keywords are cut first.

## `datasetId` (type: `string`):

Optional. A dataset of domains, websites or company names (for example from a scraper run). Each item is checked and the result columns are added next to its fields. Use {{resource.defaultDatasetId}} in an integration.

## `domainFields` (type: `array`):

Item fields to take a domain from, in order of preference. Dotted paths work (company.website). Default: domain, website, url, email.

## `nameFields` (type: `array`):

Optional. Item fields holding a company or brand name (for example title, companyName). Used when an item has no domain: the name is turned into domain ideas with the TLDs, prefixes and suffixes above. Legal forms at the end (Ltd, Inc, GmbH…) are dropped.

## `keepItemFields` (type: `boolean`):

On: each output row is the original item plus the availability columns. Off: only the availability columns.

## `includeRegistrationDetails` (type: `boolean`):

Off (faster): names found in DNS are reported as taken without asking the registry. On: also fetch the registrar, creation and expiry dates of taken names from RDAP (WHOIS fallback).

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

Leave out names that are taken or couldn't be checked. Left-out names are free.

## `dedupe` (type: `boolean`):

Skip repeats of a domain already checked in this run. Skipped repeats are free.

## `concurrency` (type: `integer`):

How many names to check at the same time (1–25). Each registry server still gets at most 3 requests at a time.

## `maxResults` (type: `integer`):

Optional cap on output rows (each row is one domain).

## Actor input object example

```json
{
  "domains": [
    "apify.com"
  ],
  "keywords": [
    "blue fox"
  ],
  "tlds": [
    "com",
    "net",
    "org",
    "io",
    "co",
    "app",
    "dev",
    "ai"
  ],
  "hyphenVariants": false,
  "maxGenerated": 500,
  "keepItemFields": true,
  "includeRegistrationDetails": false,
  "onlyAvailable": false,
  "dedupe": true,
  "concurrency": 10
}
```

# Actor output Schema

## `items` (type: `string`):

No description

## `summary` (type: `string`):

No description

# 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 = {
    "domains": [
        "apify.com"
    ],
    "keywords": [
        "blue fox"
    ],
    "tlds": [
        "com",
        "net",
        "org",
        "io",
        "co",
        "app",
        "dev",
        "ai"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("charlesmarkette/domain-availability-checker-bulk-name-ideas").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 = {
    "domains": ["apify.com"],
    "keywords": ["blue fox"],
    "tlds": [
        "com",
        "net",
        "org",
        "io",
        "co",
        "app",
        "dev",
        "ai",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("charlesmarkette/domain-availability-checker-bulk-name-ideas").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 '{
  "domains": [
    "apify.com"
  ],
  "keywords": [
    "blue fox"
  ],
  "tlds": [
    "com",
    "net",
    "org",
    "io",
    "co",
    "app",
    "dev",
    "ai"
  ]
}' |
apify call charlesmarkette/domain-availability-checker-bulk-name-ideas --silent --output-dataset

```

## MCP server setup

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

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/wGjSvGXSVTG0sgKT2/builds/Asl98Wfec5ZsxNja5/openapi.json
