Typosquat & Lookalike Domain Detector with Threat Signals avatar

Typosquat & Lookalike Domain Detector with Threat Signals

Pricing

from $25.00 / 1,000 registered lookalike founds

Go to Apify Store
Typosquat & Lookalike Domain Detector with Threat Signals

Typosquat & Lookalike Domain Detector with Threat Signals

Find typosquatted and lookalike domains impersonating your brand: typo, homoglyph, bitsquat, TLD-swap and combosquat variants, checked against live registries and enriched with registrar, DNS, MX and TLS data to separate real threats from parked domains. Unregistered variants are never charged.

Pricing

from $25.00 / 1,000 registered lookalike founds

Rating

0.0

(0)

Developer

cottony_brittlegill

cottony_brittlegill

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

15 hours ago

Last modified

Categories

Share

Typosquat & Lookalike Domain Detector

Find the domains impersonating your brand — and tell which ones are actually dangerous.

This is a defensive tool. It is built to monitor for lookalike domains that impersonate a brand you own, or that you are explicitly authorized to protect — not to explore third-party infrastructure for its own sake. It reads only public data: domain registry records (RDAP/WHOIS), DNS answers, and — for a domain that already resolves — the TLS certificate it presents on a standard handshake. It never sends email, submits a form, logs in, scrapes page content, or otherwise interacts with a lookalike site. If a domain doesn't answer, it's recorded as unknown, not probed harder.

What it does

You give it one or more domains you own (a list, or newline/comma-separated text — brandDomains accepts bare domains or full URLs). A single run scans at most the first 50 valid brand domains supplied, in the order you listed them; this limit is fixed and not exposed as an input, and anything past the 50th is dropped — with a warning in the run log naming how many were submitted, how many were scanned, and that the rest were dropped, so it never reads as full coverage — see Honest limits. If you need to cover more than 50 domains, split them across multiple runs. For each one it:

  1. Generates lookalike candidates using 13 techniques.
  2. Checks which candidates are actually registered (DNS first, then the domain registry — see Pricing for why this order matters for cost).
  3. Enriches every registered lookalike with DNS, MX, TLS and registration data, and scores how dangerous it currently looks.
TechniqueExample (yourbrand.com / paypal.com)What it captures
omissionpaypal.compaypl.coma dropped letter
insertionpaypal.complaypal.coman extra, keyboard-adjacent letter
repetitionpaypal.compaypall.coma doubled letter (double-tapped key)
replacementyourbrand.comtourbrand.comone letter swapped for an adjacent key
transpositionpaypal.compaypla.comtwo adjacent letters swapped
hyphenationpaypal.compay-pal.coma hyphen inserted between letters
subdomainyourbrand.comyour.brand.comthe brand split so it reads as a subdomain of an unrelated domain
additionpaypal.compaypals.coman extra character appended at the end
vowelswappaypal.compeypal.comone vowel swapped for another
bitsquattingpaypal.compaypan.coma single-bit memory/transmission error in one character
homoglyphpaypal.compaypa1.coma visually similar character or IDN/Unicode lookalike
tldswapyourbrand.comyourbrand.iothe same brand label under a different TLD
combosquatyourbrand.comyourbrand-login.coma common keyword combined with the brand (login, secure, account, support, verify, billing, help, mail by default)

tldswap runs against a default list of 20 commonly abused TLDs (com, net, org, info, biz, co, io, app, online, site, shop, store, xyz, top, live, club, eu, de, uk, it) unless you supply your own. All 13 techniques run by default; you can restrict to a subset via variantKinds. Output is capped at maxVariantsPerDomain (default 400), and the cap is spread evenly across every enabled technique — so a low cap still gives you homoglyph and TLD-swap coverage instead of being consumed entirely by, say, insertion.

Why the enrichment matters

A list of "this lookalike is registered" is not actionable on its own — most registered lookalikes are dormant or parked, not phishing infrastructure. This actor tells you, per lookalike:

  • Does it have MX records — can it send or receive mail as your brand? This is the business-email-compromise vector, and it doesn't require a website at all.
  • Does it resolve to a live host (or a CNAME)?
  • Does it present a TLS certificate — a lookalike with a valid cert was built to look convincing in a browser, not just squatted and forgotten.
  • How old is the registration — newly registered lookalikes correlate with an active campaign, not background noise.
  • Is it merely parked with a domain reseller — i.e. inventory for resale, not live infrastructure?

Each finding gets a riskLevel:

riskLevelMeaning
active_threatHas MX records and (resolves live or presents a TLS cert) — mail and web infrastructure both active. The highest-concern tier.
mail_capableHas MX records but no live web presence or certificate — can still send/receive mail as the lookalike with no website at all.
live_siteResolves (or has a CNAME) but has no MX records — a site exists; it can't send mail as the brand.
parkedNameservers point at a known parking/resale provider. This is a de-escalating signal and overrides the others — a parked domain's own landing page can otherwise look like a live site.
registered_inactiveRegistered, but no active DNS records were observed at all. Lowest concern; likely dormant or reserved.
dns_incompleteThe DNS lookup for this domain partially failed (e.g. a timeout on one record type while others answered), and none of the levels above applied from confirmed evidence. This is not a clean bill of health — it means we could not fully verify mail/web capability, not that we checked and found nothing. Any positively-observed evidence (a resolved host, a certificate) is still reflected in the score and riskReasons; only the absence of a record is treated as unverified rather than confirmed. Re-run the scan if you see this.

Each record also carries a riskScore (0–100): it starts at 10 for simply being registered, then adds 25 for a live resolution or CNAME, 30 for MX records, 20 for a TLS certificate, and 15 if registered in the last 90 days. A parked classification subtracts 45 (floored at 5) — parking is the single strongest signal that a listing is inventory, not infrastructure. Every record's riskReasons array spells out exactly which of these applied, so you never have to reverse-engineer the score.

Output sample

A real, unedited finding from a run against apify.comaapify.com, a repetition-squat registered about four months earlier via NameCheap, actively resolving through Cloudflare with MX records and a live Google Trust Services certificate:

{
"brandDomain": "apify.com",
"domain": "aapify.com",
"registrableDomain": "aapify.com",
"unicodeDomain": null,
"variantKind": "repetition",
"status": "registered",
"riskLevel": "active_threat",
"riskScore": 85,
"riskReasons": [
"resolves to a live host",
"has MX records — can send or receive mail as the lookalike",
"presents a TLS certificate (Google Trust Services)"
],
"registration": {
"source": "rdap",
"registrar": "NameCheap, Inc.",
"createdAt": "2026-03-22T18:44:18Z",
"expiresAt": "2027-03-22T18:44:18Z",
"ageDays": 128,
"domainStatus": [
"client transfer prohibited"
],
"nameservers": [
"asa.ns.cloudflare.com",
"reese.ns.cloudflare.com"
]
},
"dns": {
"ns": [
"reese.ns.cloudflare.com",
"asa.ns.cloudflare.com"
],
"a": [
"188.114.96.7",
"188.114.97.7"
],
"aaaa": [
"2a06:98c1:3120::7",
"2a06:98c1:3121::7"
],
"mx": [
{ "priority": 17, "exchange": "route1.mx.cloudflare.net" },
{ "priority": 30, "exchange": "route3.mx.cloudflare.net" },
{ "priority": 42, "exchange": "route2.mx.cloudflare.net" }
],
"txt": [
"v=spf1 include:_spf.mx.cloudflare.net ~all",
"google-site-verification=1EpDqhlLgU5l6XrJC71HEn0wEHzmxOKqG7wOGhsyH5M"
],
"cname": [],
"error": null
},
"ssl": {
"issuer": "Google Trust Services",
"subjectCN": "aapify.com",
"validFrom": "2026-07-19T01:52:20.000Z",
"validTo": "2026-10-17T02:52:11.000Z",
"daysToExpiry": 79,
"san": ["aapify.com"],
"error": null
},
"errors": [],
"checkedAt": "2026-07-29T09:57:14.868Z",
"chargeable": true
}

By default (onlyRegistered: true) only records with status: "registered" are written to the dataset — the unregistered majority is not, so you see the findings you came for. Turn onlyRegistered off to get every candidate checked, registered or not, as a full audit trail; it is never billed differently either way.

Every record also carries chargeable — whether this finding qualifies to be billed (status: "registered", always). This actor writes each finding to your dataset before charging for it, specifically so a storage failure can never bill you for a finding you didn't receive (every failure mode falls on us, not you) — so by the time a record is in your dataset at all, charging for it (if chargeable) has either already happened or is about to. For the authoritative record of what a run actually charged, use the run's own Apify billing/usage panel — that is the real ledger; nothing in this dataset needs to duplicate it.

Pricing

Two pay-per-event charges, and nothing else:

EventPriceWhen it fires
actor-start$0.005Once per run.
registered-lookalike-found$0.025Once per candidate confirmed registered — never for a candidate that isn't, and never for one whose status could not be determined.

Candidates that turn out not registered are never charged, and lookups that fail or time out (status: "unknown") are never charged either — you only pay for a finding, never for our inability to get an answer.

How many findings a scan produces depends heavily on how squatted the brand already is, and that's a real cost variable worth planning around before you run at scale. Two things to know before reading the table below: first, the default maxVariantsPerDomain: 400 is an upper bound on generated variants, not a target — the generator round-robins across all 13 techniques and simply stops once it runs out of distinct candidates to produce, which for a short label like apify or google happens well before 400 (reaching 400 actually generated variants needs a brand label around 13+ characters long). Second, the "registered lookalikes" figures below count every variant with

status: "registered"
, which (in the default dns-first mode) is exactly every variant that is DNS-delegated — an RDAP/WHOIS hit is not required to bill a finding, DNS delegation alone is sufficient evidence of registration. Both figures are taken directly from a live run of the actual shipped generator and pipeline, recorded in docs/fanout-probe-report.md:

Brand profileVariants actually generated (maxVariantsPerDomain: 400)Registered lookalikesCost
An ordinary brand — about 32% of generated variants come back already registered (measured on apify.com)224 (the generator exhausts before 400)72$0.005 + 72 × $0.025 = $1.805
A heavily-squatted, very well-known brand — about 87% of generated variants come back already registered (measured on google.com), because most of its typo-variants are already taken by someone256 (the generator exhausts before 400)223$0.005 + 223 × $0.025 = $5.580

The gap between those two numbers is real, not a rounding error: for a famous brand, most lookalikes aren't hypothetical — they're already registered by someone else. Treat both figures as illustrative, not a quote for your brand — the only hard ceiling on spend is maxFindings, described next.

maxFindings (default 500, hard maximum 5000) is an upper bound on spend, not an estimate of what a run will actually cost. The scan stops the moment it reaches maxFindings, so a run can never cost more than $0.005 + maxFindings × $0.025 — at the default, that ceiling is $12.505 — regardless of how many variants you generate or how squatted the brand turns out to be; most runs, including both measured above, cost substantially less than their maxFindings ceiling. At maxFindings: 20, for example, the same formula caps a run at $0.005 + 20 × $0.025 = $0.505. Set it low (e.g. 20–50) for a first, bounded test run before scaling up.

If you scan several brand domains in one run, maxFindings is one shared budget across all of them, not a per-brand allowance. Brands are queued and checked in the order you listed them; if an early brand in the list is heavily squatted, it can consume the entire maxFindings cap by itself, and the run will stop before later brands in the same list are examined at all — the log line at the end reports a total, not a per-brand breakdown, so this is easy to miss. If you're monitoring one brand you expect to be heavily squatted alongside others you don't, run the heavily-squatted one in its own run with its own maxFindings, rather than mixing it into a multi-brand list.

verifyMode: dns-first (the default) is also a cost control, not just a speed one: it only spends a registry query on a candidate that is already DNS-delegated, instead of querying the registry for every single generated variant. Registry query concurrency is deliberately conservative — perRegistryConcurrency defaults to 2 and maxes out at 3 (globalConcurrency defaults to 10, maxing at 30) — tuned against a real rate limit we hit during live testing at higher concurrency against a heavily-delegated brand.

Honest limits

  • A run scans at most 50 brand domains. If you supply more than 50 valid domains (via brandDomains and/or brandDomainsText combined), only the first 50, in the order you listed them, are actually scanned — the rest are dropped, with no dataset entry marking them as skipped. The run log does carry a warning naming how many were submitted, how many were scanned, and that the rest were dropped, so this is visible if you check the log — but there is still no per-domain dataset marker, so a dataset-only integration (skipping the log) would miss it. This is a fixed internal limit, not an input you can raise. If you're monitoring on behalf of multiple clients (MSSP use), keep each client's domain list under 50 per run, or run one client per run if any single list might exceed it.
  • dns-first mode (the default) can miss a lookalike that is registered but has no nameservers delegated yet — it only queries the registry for candidates that already resolve or have DNS delegation. rdap-all queries the registry for every generated variant instead, catching registered-but-not-yet- delegated squats, at much higher latency and a much larger registry query volume.
  • No registrant contact data is returned. It is redacted at most registries post-GDPR, and this actor doesn't attempt to collect it even where it might still be exposed — only registrar, dates, status codes and nameservers.
  • Some ccTLDs have no RDAP service at all, or (e.g. .kg, .mg) publish only an insecure http:// endpoint that this actor deliberately won't use for a registration lookup; those fall back to WHOIS, which is far less structured than RDAP. A small number of ccTLDs have neither a usable RDAP endpoint nor a WHOIS referral — those come back as status: "unknown" and, per the pricing policy above, are never charged.
  • Homoglyph coverage is broad but not exhaustive. It covers the common Latin/Cyrillic/Greek confusables and multi-character substitutions (rn for m, digits for letters, and similar) used in real IDN homograph attacks, but it is not a substitute for a registered trademark watch service, which typically has broader and continuously updated coverage.
  • Parking detection is pattern-based against a fixed list of about 20 known parking/resale providers' nameservers (Sedo, Bodis, Afternic, HugeDomains and similar). It will not catch a parking provider that isn't on that list, or one that changes its nameserver pattern.

Typical uses

  • Brand-protection monitoring — run on a schedule against your own domains to catch new lookalikes as they're registered.
  • Pre-launch name clearance — before committing to a new product or company name, see how many lookalikes of it are already registered.
  • MSSP client reporting — run per-client and hand over the dataset (or a filtered, riskLevel-sorted view of it) as part of a recurring security report.
  • Phishing-infrastructure triage — when a lookalike domain is reported to you, use the enrichment (MX, TLS, age, parking status) to decide how urgently it needs escalating, instead of treating every registered lookalike the same.

Run it on a schedule

A single run is a snapshot; new lookalikes get registered continuously, so the useful mode of operation is recurring, not one-off. In the Apify Console, open this actor, go to Schedules, and create a schedule (e.g. weekly) with the same input you'd use for a manual run. Each scheduled run only charges for the lookalikes it actually finds registered at that point in time — there's no extra cost for scheduling itself, and no need to de-duplicate previous findings yourself unless you want to; the dataset for each run is independent.

FAQ

How can I tell if a typosquat domain is an actual threat or just parked? Check riskLevel: active_threat (MX records plus a live resolve or TLS certificate) and mail_capable (MX only) mean real mail/web infrastructure is behind the domain; parked means its nameservers match a known parking/resale provider, which is a de-escalating signal that overrides the others — see the full table above.

Does this tell me who registered a lookalike domain? No — registrant contact data is redacted at most registries post-GDPR, and this actor doesn't attempt to collect it even where it might still be exposed. You get registrar, dates, status codes and nameservers instead.

How much does scanning a well-known brand cost versus a smaller one? It depends heavily on how squatted the brand already is: a measured run against apify.com (an ordinary brand) found 72 registered lookalikes for $1.805, while google.com (heavily squatted) found 223 for $5.580 — both bounded by maxFindings (default 500, so $12.505 worst case at defaults), so a run's cost can never run away on you. See Pricing for the full breakdown.

Can I monitor for new lookalikes automatically, or is this a one-time scan? Set up a schedule in the Apify Console (e.g. weekly) with the same input — each run is an independent snapshot and only charges for what it actually finds registered at that point in time.

Part of the same domain-tooling family, same pay-per-event pricing, same "never charge for a lookup that couldn't be determined" policy:

  • Bulk Domain Intelligence — WHOIS/RDAP registration data, DNS records, SSL certificate check and availability for domains you already know. Use it to check a domain, not to discover lookalikes of one.
  • Domain Mail-Health Bulk — SPF, DMARC, DKIM and MX audit with an A-F grade. Once this actor finds a lookalike with mail_capable or active_threat risk, run that domain through Mail-Health Bulk to see exactly what mail-sending capability it has configured.