# Typosquatting Detection — Find Lookalike Domains, 1,075 TLDs (`oswaldocarabano/brand-domain-sweep`) Actor

Typosquatting detection across 1,075 gTLDs. Finds lookalike domains, domain squatting and phishing lookalikes imitating your brand, read straight from registry zone files, so every match really exists today. Brand protection domain monitoring with no WHOIS, no rate limits and no subscription.

- **URL**: https://apify.com/oswaldocarabano/brand-domain-sweep.md
- **Developed by:** [Oswaldo Carabano](https://apify.com/oswaldocarabano) (community)
- **Categories:** Developer tools, AI, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Typosquatting Detection — Find Lookalike Domains, 1,075 TLDs

Finds every delegated domain that matches, imitates or contains your brand, across the
whole gTLD namespace. It reads the registries' own zone files, so a match means the
domain **really exists today** — not that someone once registered it, not that a
scraper saw it last month.

Typosquats, homograph tricks, brand-plus-keyword domains and lookalikes in TLDs you
have never checked. One run, 1,075 TLDs.

### Coverage

**1,075 gTLDs**, including `.com`, `.net`, `.org`, `.info`, `.biz`, `.xyz`, `.top`,
`.shop`, `.online`, `.site`, `.store`, `.app`, `.dev` and `.cloud` — **255,631,856
delegated domains**, counted from the zone files themselves and refreshed daily.

Coverage is real but it is not evenly spread, and you should know the shape of it
before you rely on it: `.com` alone is 166 million of that total, and while all 1,075
TLDs are included, 481 of them hold fewer than a thousand domains each. Breadth helps
you catch something in an obscure TLD; it is not 1,075 equally busy namespaces.

**You can narrow it.** Leave *Limit to these TLDs* empty and the sweep covers all
1,075. Fill it in — `com`, `net`, `shop` — and the run is substantially faster and
cheaper, because the service skips every other TLD instead of reading through them.
If you already know which namespaces matter to your brand, say so.

**Not covered:** `.io`, `.ai`, `.co`, `.me`, `.tv`, `.cc` and every other country-code
TLD. These are not available from ICANN's zone file service at any price — they are run
outside ICANN's contracts. They are also exactly the TLDs a startup expects, so we say
it here rather than letting you find out from an empty result.

**What a zone file does not contain, and no run will ever return:** the registrant,
their email, the registrar, the registration date, the expiry date, or the domain's own
A, MX and TXT records. Any tool promising those needs a different source, and at scale
that source is prohibited by the agreement behind this data.

### Input

Every run is anchored on something you provide. There is no way to ask this Actor for
the whole namespace, and that is a design decision rather than a limitation: the data
agreement behind it forbids handing over a substantial portion of a zone, so the
product simply has no shape that could.

See **Example runs** below for fifteen worked inputs.

### Output

| Field | Meaning |
|---|---|
| `domain` | The matching domain, lowercase, in A-label form |
| `tld` | Its top-level domain |
| `match_type` | `exact`, `typo` or `contains` |
| `edit_distance` | How many characters away from your brand, for `typo` matches |
| `nameservers` | Every nameserver the domain delegates to |
| `dns_provider` | Who runs the DNS, inferred from the nameserver. **69.1%** filled. This is a hosting fact, not a technology one — see below |
| `parked_for_sale` | True when the nameserver belongs to a parking or domain-sale service. **2.0%** of domains, and exact when it fires |

### Reading the results

**A match is not an infringement.** `stripe-tools.com` may be a legitimate integration
partner and `strlpe.com` may be a parked typo nobody will ever use. This Actor tells
you what exists; deciding what to act on is your job and your lawyer's.

**`exact` is certain. `typo` and `contains` are search, not judgement.** Edit distance
2 will surface names that share letters with your brand by coincidence, especially for
short brands. If your brand is under five characters, start at distance 1.

**A domain that exists is not necessarily live.** The zone file proves delegation, not
that a website answers. Check `parked_for_sale`: a match sitting on Afternic or Sedo is
a squatter waiting to sell, which is a different problem from one running a fake shop.

**`dns_provider` says who runs the DNS, not what the site is built with.** We measured
every domain in the zone: the nameserver identifies the DNS operator for 69% of them,
but that is a hosting fact. A domain on Cloudflare can be running anything at all.
Website platforms are configured with A and CNAME records, which a zone file does not
contain, so we cannot see them and we do not guess — Shopify, for instance, is visible
on 185 domains out of 64 million. We would rather ship a column that is true than one
that looks impressive.

**An empty result is the good news**, and it only costs the $0.00001 start fee. If
nothing came back, nobody is squatting on your brand in the zones we cover today.

### Example runs

**1. Find typosquatting domains for a short brand name**

```json
{
  "brand": [
    "stripe"
  ],
  "matchTypes": [
    "exact",
    "typo"
  ],
  "maxEditDistance": 1,
  "maxResults": 100
}
```

**2. Thorough typosquat sweep with edit distance 2**

```json
{
  "brand": [
    "stripe"
  ],
  "matchTypes": [
    "exact",
    "typo",
    "contains"
  ],
  "maxEditDistance": 2,
  "maxResults": 500
}
```

**3. Check two spellings of one brand for squatters**

```json
{
  "brand": [
    "mailchimp",
    "mailchimps"
  ],
  "matchTypes": [
    "exact",
    "typo"
  ],
  "maxEditDistance": 1,
  "maxResults": 200
}
```

**4. Monitor a brand and its product names for squatting**

```json
{
  "brand": [
    "figma",
    "figjam"
  ],
  "matchTypes": [
    "exact",
    "contains"
  ],
  "maxResults": 300
}
```

**5. List exact-match brand domains across all TLDs**

```json
{
  "brand": [
    "notion"
  ],
  "matchTypes": [
    "exact"
  ],
  "maxResults": 1000
}
```

**6. Find brand plus keyword domain squatting**

```json
{
  "brand": [
    "paypal"
  ],
  "matchTypes": [
    "contains"
  ],
  "maxResults": 1000
}
```

**7. Typosquatting detection for a long brand name**

```json
{
  "brand": [
    "cloudflare"
  ],
  "matchTypes": [
    "typo"
  ],
  "maxEditDistance": 2,
  "maxResults": 500
}
```

**8. Check hyphenated variants of a two-word brand**

```json
{
  "brand": [
    "redbull",
    "red-bull"
  ],
  "matchTypes": [
    "exact",
    "typo"
  ],
  "maxEditDistance": 1,
  "maxResults": 200
}
```

**9. Typosquat check for a three-letter acronym brand**

```json
{
  "brand": [
    "ibm"
  ],
  "matchTypes": [
    "typo"
  ],
  "maxEditDistance": 1,
  "maxResults": 200
}
```

**10. Find phishing lookalike domains imitating a bank**

```json
{
  "brand": [
    "santander"
  ],
  "matchTypes": [
    "typo",
    "contains"
  ],
  "maxEditDistance": 2,
  "maxResults": 2000
}
```

**11. Full typosquatting sweep before a product launch**

```json
{
  "brand": [
    "ozempic"
  ],
  "matchTypes": [
    "exact",
    "typo",
    "contains"
  ],
  "maxEditDistance": 2,
  "maxResults": 1000
}
```

**12. Find squatted domains for a game or media title**

```json
{
  "brand": [
    "gta6"
  ],
  "matchTypes": [
    "exact",
    "contains"
  ],
  "maxResults": 500
}
```

**13. Monitor a licensed brand for unauthorised domains**

```json
{
  "brand": [
    "shopify"
  ],
  "matchTypes": [
    "exact"
  ],
  "maxResults": 500
}
```

**14. Brand protection when your brand is a common word**

```json
{
  "brand": [
    "apple"
  ],
  "matchTypes": [
    "exact"
  ],
  "maxResults": 1000
}
```

**15. Weekly scheduled typosquatting monitoring run**

```json
{
  "brand": [
    "binance"
  ],
  "matchTypes": [
    "exact",
    "typo",
    "contains"
  ],
  "maxEditDistance": 2,
  "maxResults": 5000
}
```

### Pricing

**$0.00001 to start, then $0.004 per matching domain** — about **$4 per 1,000
results**, and a default run of 100 rows costs **$0.40**.

The closest thing in the Store is a dnstwist-based typosquatting detector at **$0.03
per registered domain found — $30 per 1,000**. This is roughly **seven times cheaper**,
and it works differently: dnstwist generates permutations of your brand and then tests
whether each one resolves. This searches the registries' own zone files for what is
actually there, so it finds squats whose spelling no permutation engine would have
guessed.

### Data source

> 🛡️ **Sourced from the Registry Operators' own zone files**, obtained through ICANN's
> Centralized Zone Data Service under agreement with those operators. ICANN does not
> endorse, sponsor or review this Actor.

Built for security research, brand protection and domain analytics. The access behind
this data was granted one TLD at a time, which is why the coverage is what it is.

### Support

Found a domain the Actor missed, or a row that looks wrong? Open an issue on the Actor
page with the exact input you used. Zone data is refreshed once a day, so a domain
delegated this morning may not appear until tomorrow's snapshot.

# Actor input Schema

## `brand` (type: `array`):

The word or words to look for. Letters, digits and hyphens. This is what anchors the search — there is no way to ask for every domain.

## `tld` (type: `array`):

Optional. Restrict the sweep to these TLDs, for example com, net, shop. Leave empty to sweep all 1,075 covered TLDs. Narrowing makes the run substantially faster and cheaper, because the service can skip every other TLD instead of scanning them.

## `matchTypes` (type: `array`):

exact: the label is your brand. typo: one or two characters away. contains: your brand appears inside a longer name.

## `maxEditDistance` (type: `integer`):

How far a typo may be from the brand. 1 is conservative, 2 is thorough and noisier.

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

Hard cap on rows returned. Kept low on purpose so a first run cannot burn your free credit. Raise it deliberately. The service will never return more than 50,000 rows in one run.

## Actor input object example

```json
{
  "brand": [
    "stripe"
  ],
  "tld": [
    "com",
    "net",
    "org"
  ],
  "matchTypes": [
    "exact",
    "typo",
    "contains"
  ],
  "maxEditDistance": 2,
  "maxResults": 100
}
```

# Actor output Schema

## `dataset` (type: `string`):

Typosquatting detection across 1,075 gTLDs. Finds lookalike domains, domain squatting and phishing lookalikes imitating your brand, read straight from registry zone files, so every match really exists today. Brand protection domain monitoring with no WHOIS, no rate limits and no subscription.

## `runSummary` (type: `string`):

How many rows matched, whether the row cap truncated the answer, and the date of the zone data used. If truncated is true, you are seeing a partial answer.

# 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 = {
    "brand": [
        "stripe"
    ],
    "tld": [
        "com",
        "net",
        "org"
    ],
    "matchTypes": [
        "exact",
        "typo",
        "contains"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("oswaldocarabano/brand-domain-sweep").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 = {
    "brand": ["stripe"],
    "tld": [
        "com",
        "net",
        "org",
    ],
    "matchTypes": [
        "exact",
        "typo",
        "contains",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("oswaldocarabano/brand-domain-sweep").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 '{
  "brand": [
    "stripe"
  ],
  "tld": [
    "com",
    "net",
    "org"
  ],
  "matchTypes": [
    "exact",
    "typo",
    "contains"
  ]
}' |
apify call oswaldocarabano/brand-domain-sweep --silent --output-dataset

```

## MCP server setup

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

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/fIY7rPS5U4Zw97Zzp/builds/V4vAJq5bCO0jxuxap/openapi.json
