# Typosquat & Brand Domain Monitor (`arched_friend/typosquat-monitor`) Actor

Generate the lookalike domains of your brand, find out which are already registered, and see which of those can host a website or send email. Run it on a schedule and get alerted the day a new lookalike is registered, which is usually days before a phishing campaign starts.

- **URL**: https://apify.com/arched\_friend/typosquat-monitor.md
- **Developed by:** [Peach O](https://apify.com/arched_friend) (community)
- **Categories:** Developer tools, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$20.00 / 1,000 brand domain monitoreds

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

## Typosquat & Brand Domain Monitor: Find the Fakes Before Your Customers Do

Generate every plausible lookalike of your domain, find out which are already registered, and see which of those can serve a website or send email. Run it on a schedule and you hear about a new lookalike the day it is registered — usually days before it is pointed at your customers.

Built for brand, security and legal teams who currently find out about a phishing domain from a customer complaint.

### How it works

```mermaid
flowchart LR
    A["yourbrand.com"] --> B["Generate lookalikes:<br/>typos, homoglyphs,<br/>login-yourbrand, other TLDs"]
    B --> C["DNS: does it exist?"]
    C -->|no| D["available"]
    C -->|yes| E["RDAP: registrar, age"]
    E --> F["Website? Mail records?"]
    F --> G["Risk score"]
    G --> H[("Newly registered<br/>= the alert")]
```

DNS does the cheap first pass, so thousands of candidates reduce to the handful that actually exist before anything heavier runs. A real run checked 105 lookalikes of `apify.com` in **under 4 seconds** and found 34 registered.

### The score is about capability, not similarity

A parked domain nobody has wired up is a nuisance. One with **both a website and mail records** is a phishing kit waiting for a target list. The score weights exactly that:

| Signal | Why it matters |
| --- | --- |
| Registered | Someone owns it |
| Has a website | It can serve a fake login page |
| **Has mail records** | It can send email that looks like it came from you |
| Homoglyph pattern | Using `rn` for `m` or `0` for `o` is deliberate, not a typo |
| `login-` / `-secure` affix | Built to look like your sign-in page |
| Registered in the last 30 days | Fresh registrations are the ones that get used |

### Built for

- **Security teams** watching for phishing infrastructure before a campaign starts
- **Brand and legal teams** building evidence for a UDRP complaint or takedown
- **Ecommerce** operators whose customers get targeted with fake stores
- **Anyone** deciding which defensive registrations are actually worth paying for

### Input

```json
{
  "domains": ["yourbrand.com"],
  "onlyRegistered": true,
  "onlyChanged": true
}
```

| Setting | What it does |
| --- | --- |
| `domains` | The brand domains to protect |
| `strategies` | Which typo patterns to generate |
| `extraTlds` | Check your exact name under other extensions |
| `includeAffixes` | Also generate `login-yourbrand.com` style names |
| `onlyRegistered` | Turn **off** to see what is still available to register defensively |
| `onlyChanged` | Only newly registered lookalikes — the scheduled-alert setting |

### Output

```json
{
  "brand": "apify.com",
  "candidate": "appify.com",
  "strategy": "repetition",
  "isRegistered": true,
  "hasWebsite": true,
  "hasMx": true,
  "registrar": "GoDaddy.com, LLC",
  "registeredAt": "2019-04-02T10:15:00Z",
  "ageDays": 2725,
  "riskScore": 80,
  "riskLevel": "high",
  "riskReasons": [
    "The domain is registered.",
    "It serves a website.",
    "It has mail records, so it can send email that looks like yours."
  ],
  "changeType": "unchanged",
  "checkedAt": "2026-09-17T18:33:10.442Z"
}
```

`riskReasons` is written in plain language so a row can be pasted straight into a ticket or a takedown request without translation.

### Turn it into a brand alert

```json
{
  "domains": ["yourbrand.com"],
  "onlyChanged": true
}
```

Schedule it daily. The first run maps what already exists. Every run after returns only `newly-registered`, `website-appeared` and `mail-configured` — the three transitions that mean someone is preparing to use a domain against you.

### Run it as an API

```bash
curl -X POST "https://api.apify.com/v2/acts/arched_friend~typosquat-monitor/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "domains": ["yourbrand.com"],
    "onlyRegistered": true
  }'
```

### Pricing

You pay $0.02 for each brand domain monitored, however many hundreds of lookalikes that generates.

| Watching 3 brand domains daily | Monthly cost |
| --- | --- |
| Checking by hand | not realistically possible |
| Brand protection services | $200 to $2,000 per month |
| This Actor | $1.80 per month |

### Common questions

**Does a registered lookalike mean I am being attacked?** No. Many are owned by domain investors, by your own company, or by someone with a genuinely similar name. That is why the output separates parked domains from ones with a website and mail configured.

**Why is a domain "registered" when nothing loads?** Because it resolves — it has nameservers even if no web server answers. That is the normal parked state, and it is worth knowing about before a page appears on it.

**Can it check every TLD?** It checks your name under the extensions you list, plus typo variants of your existing extension. Checking all 1,500 extensions would be slow and mostly noise; the list defaults to the ones squatters actually use.

**Does it work for `.co.uk`?** Yes. Two-part suffixes are handled properly, so `yourbrand.co.uk` generates `yourbrnad.co.uk` rather than nonsense.

### Related products

- **Domain & SSL Monitor** to watch expiry and certificates on the domains you own
- **Website Change Monitor** to watch a lookalike once it starts serving a page
- **Email Deliverability Checker** to confirm your own SPF and DMARC are strong enough to blunt a lookalike sender
- **Tech Stack Checker** to profile what a suspicious lookalike is actually running

# Actor input Schema

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

The domains you want to protect, one per line, for example yourbrand.com. Lookalikes are generated from each one.

## `strategies` (type: `array`):

Which lookalike patterns to generate: omission, transposition, repetition, substitution, homoglyph, hyphenation.

## `extraTlds` (type: `array`):

Check your exact brand name under these extensions too. A same-name different-extension registration is the commonest squat of all.

## `includeAffixes` (type: `boolean`):

Also generate names like login-yourbrand.com and yourbrand-secure.com, which is what phishing pages usually use.

## `affixWords` (type: `array`):

The words used to build those names.

## `maxCandidatesPerDomain` (type: `integer`):

Upper limit on how many lookalikes to generate and check for each brand domain.

## `onlyRegistered` (type: `boolean`):

Return only domains that actually exist. Turn this off to see which lookalikes are still available for you to register defensively.

## `onlyChanged` (type: `boolean`):

Return only newly registered lookalikes and ones that just gained a website or mail records. Turn this on for scheduled monitoring.

## `lookupRegistrationDetails` (type: `boolean`):

Query RDAP for each registered lookalike to get its registrar and age. A freshly registered lookalike is the highest-risk kind.

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

How many candidates to check at once.

## `requestTimeoutSecs` (type: `integer`):

How long to wait for each registration lookup.

## Actor input object example

```json
{
  "domains": [
    "apify.com"
  ],
  "strategies": [
    "omission",
    "transposition",
    "repetition",
    "substitution",
    "homoglyph",
    "hyphenation"
  ],
  "extraTlds": [
    "com",
    "net",
    "org",
    "co",
    "io",
    "app",
    "shop",
    "online",
    "site"
  ],
  "includeAffixes": true,
  "affixWords": [
    "login",
    "secure",
    "account",
    "support",
    "help",
    "billing",
    "pay",
    "verify",
    "update",
    "mail",
    "app",
    "my",
    "portal",
    "signin"
  ],
  "maxCandidatesPerDomain": 800,
  "onlyRegistered": true,
  "onlyChanged": false,
  "lookupRegistrationDetails": true,
  "concurrency": 25,
  "requestTimeoutSecs": 15
}
```

# Actor output Schema

## `domains` (type: `string`):

One row per lookalike, with whether it is registered, whether it can host a website or send mail, its registrar and age, and a risk score.

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

How many lookalikes exist, how many are armed with a website or mail, which typo patterns squatters are using, and the highest-risk domains with reasons.

# 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"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("arched_friend/typosquat-monitor").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"] }

# Run the Actor and wait for it to finish
run = client.actor("arched_friend/typosquat-monitor").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"
  ]
}' |
apify call arched_friend/typosquat-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,arched_friend/typosquat-monitor"
        }
    }
}
```

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/Cnlw6YteeDEE6NLOL/builds/mgYnmh570UzPZX4zH/openapi.json
