Skip to main content

Enterprise Domain Mapper

CI Python 3.10+ License: MIT

Map enterprise corporate structures to enrichable domains. Feed it company names, get back subsidiaries, acquisitions, and regional domains that your enrichment tools are missing.

Every sales team doing enterprise ABM hits the same wall: large companies have dozens of subsidiaries, acquisitions, and regional entities, each with their own email domain. Without a complete domain map, tools like Clay and Apollo only find contacts at the parent domain. Entire business units get missed.

This tool fixes that.

$ domain-mapper "HSBC" --domain hsbc.com --verify-dns

HSBC
├── · Hang Seng Bank           hangsengbank.com        [Name guess] resolves (no MX)
├── ✓ HSBC Bank Middle East    hsbcbankmiddleeast.com  [Name guess] ✓ MX verified
├── ✓ HSBC UK                  hsbc.co.uk              [TLD guess]  ✓ MX verified
├── ✓ HSBC Bank Hong Kong      hsbc.com.hk             [TLD guess]  ✓ MX verified
├── ✓ HSBC Bank Australia      hsbc.com.au             [TLD guess]  ✓ MX verified
├── ✓ HSBC Bank India          hsbc.co.in              [TLD guess]  ✓ MX verified
└── ✓ HSBC Bank Malaysia       hsbc.com.my             [TLD guess]  ✓ MX verified

Found 14 subsidiaries, 52 domains (52 guessed, 6 MX verified)

The tree above is abridged: the run generates 52 candidate domains and six of them have live mail. Pass --output results.csv to get all of them with their sources and confidence.

The problem

Enterprise accounts don't operate under a single domain. A company like HSBC runs distinctly branded subsidiaries such as First Direct alongside regional banks in dozens of countries, each with its own domain. Deloitte has member firms. Nestlé sits over hundreds of consumer brands that use completely different domains.

If you're running enrichment against just hsbc.com, you're finding maybe 30% of the contacts you could be reaching. The rest are hiding behind firstdirect.com, hsbc.co.uk, hsbc.com.hk, and domains you didn't know existed.

Building these domain maps manually takes hours per account. We built this tool because we got tired of doing it by hand.

Quick start

Installation

pip install enterprise-domain-mapper

Or clone and install locally:

git clone https://github.com/gtmlayer/enterprise-domain-mapper.git
cd enterprise-domain-mapper
pip install -e .

Single company lookup

domain-mapper "Boeing"

Pass the parent domain when you know it. Regional TLD guessing builds from that stem, so without it you get subsidiary names and .com guesses but no hsbc.co.uk:

domain-mapper "HSBC" --domain hsbc.com --verify-dns

In batch mode the domain column supplies this per row, so --domain is not needed.

Batch mode (CSV input)

domain-mapper accounts.csv --output results.csv

Your input CSV just needs a column with company names. The tool auto-detects columns named company_name, company, name, or account. If you have a domain column (domain, website, url), it'll use that as the parent domain for TLD guessing.

With DNS verification

domain-mapper accounts.csv --output results.csv --verify-dns

This checks whether guessed domains actually have mail infrastructure (MX records) or at minimum resolve (A records). Adds a few seconds per company but filters out the noise.

What it does

The tool combines three data sources and a verification layer to build comprehensive domain maps:

1. SEC EDGAR Exhibit 21 scraper

For US-listed companies, SEC filings include Exhibit 21: a legally required list of all subsidiaries. The tool looks up the company's CIK, finds the latest 10-K filing, and parses the subsidiary list with jurisdictions.

This is the highest-quality source - it's legally mandated disclosure, so it's comprehensive and current.

2. Wikipedia corporate structure parser

For non-US companies (or supplementary data), the tool searches Wikipedia for the company page and extracts subsidiary and acquisition data from infoboxes and structured sections.

Covers companies globally, though data depth varies by how well-maintained the Wikipedia page is.

3. TLD pattern generator

Once subsidiaries are identified with their jurisdictions, the tool generates likely domain patterns. A subsidiary in Italy with parent domain hsbc.com produces guesses like hsbc.it. Covers 70+ countries with their standard corporate TLD patterns (e.g. UK produces co.uk and .uk, Japan produces co.jp and .jp).

4. DNS verification (optional)

MX record lookup with A record fallback to confirm guessed domains actually resolve. A records confirm the domain exists even without mail setup.

Two limits worth knowing, because both used to produce false confidence:

  • An MX record is not always mail. Registrars and parking pages publish a null MX (RFC 7505 ., or localhost, or 0.0.0.0). luxembourg.com and unitedkingdom.com both do. Those are treated as no mail at all.
  • Mail is not ownership. A guessed domain with live mail proves somebody owns it, not that the company you asked about does. So a guess is capped at Medium however well it resolves.

Output format

Detailed output (default)

Ten columns, one row per subsidiary-domain pair:

Column Description
parent_company The company you looked up
parent_domain Known parent domain
subsidiary_name Name of the subsidiary or entity
subsidiary_type Subsidiary, acquisition, division, etc.
jurisdiction Country or region
domain Known or guessed domain
domain_source Where it came from (SEC EDGAR, Wikipedia, TLD guess, Name guess)
dns_verified True only when the domain has MX (mail) records
dns_status DNS result: mx, a-only (resolves but no mail), unresolved, or blank if not checked
confidence High = the domain came from a source (a filing or an article); Medium = a guess with live mail, or an unverified name guess; Low = an unverified regional guess. A guessed domain never reaches High on DNS alone, because mail on chaseuk.com proves a stranger parked it, not that Chase owns it

Clay import format

One row per company with domains consolidated into a single field, ready for direct import into Clay as a data source.

domain-mapper accounts.csv --output results.csv --format clay

Importing into Clay

  1. Run the tool with --format clay to get the Clay-optimised output
  2. In Clay, create a new table or add to an existing one
  3. Import the CSV - the columns map directly to Clay's expected format
  4. Use the domain list column with Clay's enrichment tools to find contacts across all mapped domains

This is the workflow that sparked the whole tool. We were manually building domain maps for a client's enterprise accounts and realised the process was repeatable enough to automate.

Example

The examples/ directory contains input_sample.csv with five test companies to get you started:

domain-mapper examples/input_sample.csv --output examples/results.csv --verify-dns

Contributing

Want to add a new data source? The architecture makes it straightforward:

  1. Create a new module in src/domain_mapper/sources/
  2. Implement a class with a get_subsidiaries(company_name) method that returns a list of subsidiary objects
  3. Add it to the orchestrator in mapper.py
  4. Write tests in tests/

Some data sources we'd love to see contributed:

  • Companies House (UK company registry)
  • OpenCorporates API
  • Crunchbase (acquisitions data)
  • D&B corporate hierarchies

Pull requests welcome. Run ruff check and black before submitting, and make sure pytest passes.

Tech stack

  • Python 3.10+
  • requests and beautifulsoup4 for web scraping
  • click for the CLI
  • rich for terminal output
  • No paid APIs, no API keys required

Built by GTM Layer

GTM Layer builds revenue systems for B2B sales teams. We work with companies on CRM architecture, enrichment pipelines, signal-driven outbound, and everything in between.

This tool came out of real client work - we built it to solve a problem we kept hitting on enterprise ABM engagements. If you're running into similar challenges, get in touch.

Licence

MIT - use it however you want.

Metadata

Release files for enterprise-domain-mapper 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for enterprise-domain-mapper 0.2.0
File Size Uploaded
enterprise_domain_mapper-0.2.0.tar.gz 36.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for enterprise-domain-mapper 0.2.0
File Interpreter ABI Platform
enterprise_domain_mapper-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 64.3 kB

Release files / enterprise_domain_mapper-0.2.0.tar.gz

Download URL enterprise_domain_mapper-0.2.0.tar.gz
Size 36.0 kB
Tags Source
SHA-256 checksum
How to use checksums
26d57557491c005f47f4cb11f0f85f4c6ed67ac65e58a62f20941672abece6d7
BLAKE2b-256 checksum
How to use checksums
d43833c2bbfb6b67f7ed3fe63e56dcd8dcdcb20ed29b6f4a5489c4dad0e87322
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / enterprise_domain_mapper-0.2.0-py3-none-any.whl

Download URL enterprise_domain_mapper-0.2.0-py3-none-any.whl
Size 28.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
35b525676c2d48ce873fd01f619c415ffee4b3f7d47daf59e13446c33a6f3031
BLAKE2b-256 checksum
How to use checksums
aef3ffd1dfd180d3b89a6cf74d82aaba0fb97e6f44cec5e30f1af603020ef45e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release history Release notifications | RSS feed

0.2.1

2 release files

This release

0.2.0 This release

2 release files

0.1.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page