Infrastructure and registration tools
Four tools describe how domains relate through their DNS infrastructure and their registrations:
| Tool | Answers |
|---|---|
datapulse_dns_dptechsim | Which domains have DNS infrastructure similar to this one |
datapulse_dns_neighborhood | Which infrastructure cluster a domain belongs to, and what that cluster looks like |
datapulse_dns_regclusters | Which registrars registered unusually many domains on a given UTC day, and which domains |
datapulse_dns_registrar | Who a registrar ID is, or which registrars match a name |
Input spelling, submitted_domain and paging fields follow the shared rules in datapulse_help(topic="conventions"). Investigation workflows that combine these tools are in datapulse_help(topic="reconnaissance"), datapulse_help(topic="lookalike_domains") and datapulse_help(topic="malicious_bulk_regs").
The similarity signals
dptechsim and neighborhood share one representation of a domain: a 1000-dimensional embedding built from 100 dimensions each of operational nameservers, their ASNs, reported (configured) nameservers, their ASNs, MX hostnames, MX ASNs, A/AAAA ASNs, TLD, registrar ID and registration date. PCA reduces it for the index; cosine similarity compares two domains.
A domain’s fingerprints are taken when it enters the index and are replaced only when it is loaded again, so a fingerprint can lag live DNS by months: github.com’s MX fingerprint still read google.com after its MX moved to Outlook on 2026-04-01. The output carries no date. datapulse_live_dns gives the current records and datapulse_dns_dphistory the change log.
Shared infrastructure is evidence of a shared hosting stack, not of a shared operator. Millions of domains share Cloudflare (AS13335), Google Cloud (AS15169) or AWS, so overlap on those means little; overlap on a custom nameserver, a boutique hosting ASN or a matching MX setup means much more.
datapulse_dns_dptechsim
Finds domains whose embedding is close to a seed domain’s.
| Parameter | Type | Required | Description |
|---|---|---|---|
domain | string | Yes | Seed domain (IDN accepted). No labels are removed, so www.example.com is looked up as www.example.com; a single label is refused |
similarity | number | No | Cosine threshold, 0.75 to 1.00, default 0.95; outside that range is refused |
Response
CSV, one row per domain, most similar first, every value as the similarity service sent it (hostnames case-folded, cosine_similarity unrounded):
name,registrar_iana_id,registration_date,fpons,fpons_asn,fprns,fprns_asn,fpmx,fpmx_asn,fpaw_asn,cosine_similarity
amazon.co.uk,,,amzndns.co.uk*amzndn,12008*399169,amzndns.co.uk*amzndn,12008*399169,amazon.com,16509,16509,1
imdbpro.co.uk,,,amzndns.co.uk*amzndn,12008*399169,amzndns.co.uk*amzndn,12008*399169,amazon.com,16509,14618*16509,0.953102484252746
bbc.com,69,1989-07-15T04:00:00Z,bbc.co.uk*bbc.com,62597*63911,bbc.co.uk*bbc.com,62597*63911,messagelabs.com,396982,54113,1
(Real rows, captured 2026-10-02.) fpons/fprns are the operational and reported nameserver fingerprints, fpmx the MX fingerprint, and the *_asn columns the ASNs behind them; multi-value fields are *-delimited and cut to 20 characters by the service. An empty registrar_iana_id or registration_date means the index holds no value (every .uk name and many gTLD names); see “Registrar identifiers”.
- Result limit. A reply holds at most the number of domains the tool description states. A reply that reaches it carries the hint
complete: false (the N-domain result limit was reached; ...): more domains clear the threshold and the rows are the most similar ones. There is no paging; a highersimilaritynarrows the set. - No rows. The header row comes back with a hint as a second content item (prose, not a CSV row). It has two causes the service does not tell apart: no domain reached the threshold, or the approximate index search missed the seed itself. An exact search would return the seed at similarity 1, but a seed whose infrastructure very many domains share (a parked or default hosting stack) can be lost among thousands of identical vectors:
example.comandbbc.co.ukare both in the index and both come back empty this way. Loweringsimilarityhelps only in the first case. - Errors are plain-text tool errors: a missing
domain, asimilarityoutside 0.75–1.00 or not a finite number, orsimserver: <the daemon's message>.
Reading the score
| Score | Reading |
|---|---|
| 0.98–1.00 | Near-identical fingerprints: the same hosting stack |
| 0.95–0.98 | The same nameservers, mail and hosting networks, with minor differences |
| 0.90–0.95 | Major components shared |
| 0.85–0.90 | Similar patterns; CDN and large-provider overlap starts to dominate |
| 0.75–0.85 | Loose overlap, often only a common provider |
No score establishes a common operator. A 0.85 between two Cloudflare domains says less than a 0.85 between two domains on a boutique host: the fingerprint columns show which, and rare nameservers and ASNs carry more weight than common ones. Registrar and registration date are part of the embedding, so a clustered registration date or a shared small registrar raises the score as well.
datapulse_dns_neighborhood
Every domain in the index belongs to exactly one HDBSCAN cluster of its embedding: 351 normal clusters and 25 anomaly clusters cover 409M domains, with no unassigned points.
| Parameter | Type | Required | Description |
|---|---|---|---|
domain | string | One of domain / cluster_id | The domain whose cluster is returned (no labels removed; a single label is refused) |
cluster_id | integer | One of domain / cluster_id | A cluster, returned directly |
is_anomaly | boolean | No | With cluster_id only: true for an anomaly cluster ID (default false) |
Exactly one of domain and cluster_id is given. A null or blank argument counts as absent; is_anomaly: true with domain is refused.
Response
A JSON array with one row. A domain lookup:
[{
"domain": "google.com",
"cluster_id": 338,
"is_anomaly": false,
"anomaly_score": 0.815,
"nearest_normal_dist": 0.815,
"cluster_name": "awsdns.com*awsdns.org*googledomains.com",
"cluster_notes": null,
"member_count": 135874,
"core_sample_count": 1000,
"radius": 1.069,
"mean_density": 1.342,
"mean_anomaly_score": null,
"max_anomaly_score": null,
"exemplar_domain": "android-anti-virus.com"
}]
A cluster_id lookup returns the same row without domain, anomaly_score and nearest_normal_dist.
| Field | Meaning |
|---|---|
cluster_id, is_anomaly | The cluster and its kind |
anomaly_score | The domain’s distance from its cluster’s centre (lower is closer) |
nearest_normal_dist | Distance to the nearest normal cluster: equal to anomaly_score for a normal cluster’s members, and how far an anomaly member sits from normal infrastructure |
cluster_name | Normal clusters only: a label built from the most common nameserver patterns across all members. It does not describe any one member’s DNS; a domain can sit in a cluster on the strength of its other dimensions |
cluster_notes | Optional annotation |
member_count | Domains in the cluster |
core_sample_count, radius, mean_density | Normal clusters only: HDBSCAN core samples, radius and average density |
mean_anomaly_score, max_anomaly_score | Anomaly clusters only |
exemplar_domain | The member closest to the centroid (lowest anomaly_score): the most typical domain of the cluster, and a good seed for dptechsim |
What a cluster can and cannot show
A cluster groups domains by infrastructure shape across 409M names; the largest hold over a hundred thousand members. Sharing a cluster says two domains are built alike, typically on the same providers. It does not link them to one operator, a registrar or a registration period, and a cluster has no time dimension. For closeness to one specific domain, dptechsim ranks neighbours by score; for ownership, see datapulse_help(topic="rdap").
datapulse_dns_regclusters
Registrations grouped by registrar for one UTC day, from the corpus’s RDAP registration records.
| Parameter | Type | Required | Description |
|---|---|---|---|
date | string | No | YYYY-MM-DD, a UTC day (00:00–24:00 UTC). Default: see “The day answered” |
min_cluster_size | integer | No | Summary mode: the fewest domains a registrar needs that day to be listed, 2 or more, default 8 |
limit | integer | No | Summary mode: clusters, default 25, max 80. Detail mode: domains per page, default 200, max 500. Larger values are capped; 0 or less is the default |
offset | integer | No | Detail mode: domains to skip, from next_offset; a negative offset is refused |
registrar_id | integer | No | Selects detail mode: the registrar as a summary row reports it |
An argument for the other mode (min_cluster_size with registrar_id, offset without it) is refused unless it holds its default.
Summary mode
The largest clusters, by domain_count descending, each with up to 10 sample domains (illustrations, not the cluster):
{
"date": "2026-10-01",
"returned": 2,
"truncated": false,
"clusters": [
{"registrar_id": 146, "registrar_id_scheme": "iana", "registrar_name": "GoDaddy.com, LLC",
"domain_count": 22341, "sample_domains": ["example1.com", "example2.net", "example3.org"]},
{"registrar_id": 930834408, "registrar_id_scheme": "registry",
"domain_count": 373, "sample_domains": ["a2gprofilering.no", "aasemulen.no", "acacia.no"]}
]
}
Summary mode has no pages and no total (the database does not count the clusters it leaves out). When limit clusters come back, complete: false and the note say more clusters at or above min_cluster_size may exist; a higher limit (up to 80) or min_cluster_size is the remedy.
Detail mode
Every domain one registrar registered that day, alphabetically, the registrar stated once:
{
"date": "2025-02-09",
"registrar_id": 3222,
"registrar_id_scheme": "iana",
"registrar_name": "Domainipr Limited",
"total": 349,
"returned": 200,
"offset": 0,
"truncated": true,
"next_offset": 200,
"note": "Showing domains 1-200 of 349: a SUBSET, not every one; pass date=2025-02-09 and offset=200 for the next page.",
"domains": [
{"name": "003370.com", "registration_date": "2025-02-09T11:45:42Z"},
{"name": "0755bzh.com", "registration_date": "2025-02-09T11:25:47Z"}
]
}
total is the registrar’s domains that day. An offset past the last domain returns an empty page whose note gives the total. An empty answer in either mode is an empty list with a note.
The day answered
Without date, the tool reads the last 7 UTC days (today included) and answers the most recent day whose volume is at least half the median of the days that have rows; the note names the day used and any newer day skipped as still being ingested. Volume is measured the same way for every call in a mode (summary: the summed domain_count of the 25 largest clusters of 8 or more; detail: the registrar’s total that day), so limit, offset and min_cluster_size never change which day is answered, and every next-page note names date=. An explicit date is answered as given.
A day’s registrations keep arriving for up to about three weeks, so a recent day’s counts are floors and still growing; the note says so for a date in that window. A low count on a recent day is not a drop in activity.
Scale
On a settled day the 25 largest clusters hold 210,000–275,000 registrations (2026-09-30 to 2026-10-04), and GoDaddy (IANA 146) alone registered 24,000–62,000 a day that week. Volumes like these are normal for large retail registrars; min_cluster_size=100 or more filters them out.
datapulse_dns_registrar
The IANA registrar list (about 4,100 registrars, accredited and terminated, refreshed daily from IANA’s assignments), by ID or by name.
| Parameter | Type | Required | Description |
|---|---|---|---|
iana_id | integer | One of iana_id / search | Exact lookup by IANA registrar ID (1 or more) |
search | string | One of iana_id / search | Case-insensitive substring of the registrar name, at least 3 characters |
limit | integer | No | Search mode: registrars per page, default 250, max 500 (capped); 0 or less is the default. A row is about 90 bytes |
offset | integer | No | Search mode: registrars to skip, from next_offset; a negative offset is refused |
Exactly one of iana_id and search is given; a null or blank one counts as absent. limit and offset belong to search mode and are refused with iana_id unless they hold a default.
Response
One object in both modes, rows in IANA ID order:
{
"registrars": [
{"domain_count": 64813734, "iana_id": 146, "name": "GoDaddy.com, LLC", "status": "Accredited"},
{"domain_count": 334989, "iana_id": 1659, "name": "GoDaddy Online Services Cayman Islands Ltd.", "status": "Accredited"}
],
"returned": 2,
"offset": 0,
"truncated": true,
"next_offset": 2,
"note": "Showing registrars 1-2 of more: a SUBSET, not every match; pass offset=2 for the next page."
}
({"search": "godaddy", "limit": 2}, live 2026-10-19.) total is present whenever it is known: every ID-mode answer, and the search page that reaches the last match; earlier search pages are cut from the matches without counting them all. An ID or a search with no match is an empty registrars list, total: 0 and a note; an offset past the last match is an empty page whose note gives the number of matches.
| Field | Meaning |
|---|---|
iana_id | IANA registrar ID |
name | Registrar name |
status | Accreditation status, e.g. Accredited, Terminated |
domain_count | Portfolio size from ICANN’s Metrica reporting; 0 when no scored snapshot exists. A shared small registrar is a signal; a shared mega or brand-protection registrar is not |
Registrars sell and manage registrations; this tool does not identify registrants.
Registrar identifiers
The registrar number in DataPulse data is whatever the registry’s RDAP published, and not every registry publishes IANA IDs.
- regclusters reports it as
registrar_idwithregistrar_id_scheme:iana(an IANA ID, withregistrar_name, resolvable withdatapulse_dns_registrar(iana_id=...)),registry(the registry’s own registrar number, such as Norid’s organisation numbers for.no, which no IANA lookup can resolve), orunresolved(the IANA list could not be consulted for this call, or the identifier is not a number).registrar_idis the value to pass back asregistrar_idwhatever its scheme. - dptechsim reports the same registry-published number as
registrar_iana_id. An empty cell means the index holds no value (NULL), not IANA ID 0. - RDAP reports
ianaid: 0when the registry assigns no IANA registrar IDs (Nominet.ukamong others);datapulse_dns_registrar(iana_id=0)says so instead of looking it up.
Generated from the live server (DataPulse MCP v0.9-323-g8d4469c) on October 19, 2026. Your AI assistant reads this page by calling datapulse_help(topic="infrastructure").