DEV Community

Axel Freeman
Axel Freeman

Posted on Originally published at axelfreeman.com

I enriched 6,955 company domains. Only 1,040 of them publish an address

I enriched 6,955 company domains. Only 1,040 of them publish an address

Six thousand nine hundred fifty-five company domains, forty-five public sources, one working day. That is the
file behind this post. The number worth arguing about is not the total — it is 1,040: the rows where the
company itself published an address you can write to. Fifteen percent.

That gap is the whole business of B2B data enrichment, and most vendors fill it with the wrong thing.

Where the domains came from, and what each family actually yields

Every row in the file carries its source and the live check it passed. Counted row by row, not estimated:

Source family Domains Published an address Yield
Hacker News "Who is hiring?" threads (2024 → Sep 2026) 2,792 304 11%
Y Combinator open-source hiring directory 736 0 0%
remoteintech/remote-jobs public catalog 531 0 0%
Agency directories (DAN / Semrush listings) 492 492 100%
Show HN launches — domain taken from the post URL 407 44 11%
SaaSHub category listings (catalog outbound link) 351 0 0%
WordPress plugin directory homepage fields 350 9 3%
GitHub repository and organisation website fields 466 33 7%
dev.to posts whose canonical is a company domain 220 40 18%
Job feeds (WeWorkRemotely, Jobicy, Arbeitnow, RemoteOK, Remotive) 215 92 43%
npm, crates.io and package-registry homepage fields 190 0 0%
Reddit, Mastodon, Product Hunt and HN signal threads 142 22 15%
Total 6,955 1,040 15%

Two readings matter more than the total.

Hiring threads give you companies, not contacts. 2,792 domains — 40% of the file — and 304 mailboxes,
because the post names the employer and not the person. That is the raw material an enrichment step has to work
with.

Directories give you contacts, not prospects. Agency directories publish an address for 492 of 492 rows,
because agencies put one on their own site on purpose. A list built only from job feeds is a list of companies; a
list built only from directories is a list of competitors.

What public sources can append — and what they cannot

Appendable, because it is observable:

  • company identity — name, root domain, and the exact page the domain was taken from;
  • what they sell — product category, whether a pricing page and a self-serve sign-up exist;
  • hiring signal — open roles and titles, the cheapest honest intent signal;
  • public addresses — role and generic mailboxes published on their own domain;
  • channel hints — blog, docs, changelog, marketplace listing.

Sold as enrichment, but not observable:

  • personal mobiles — not public; anything sold as such is scraped, stale or invented;
  • revenue and headcount — third-party estimates with no published method;
  • intent and "in-market" scores — a vendor model, not an observation;
  • technographics — guessed from headers and script tags, right often enough to be dangerous.

Once you accept that split, the pricing model of the market flips. What is worth money cannot be bought in bulk,
so it has to be observed one row at a time.

The three checks a row survives before it counts as enriched

1. The domain comes from the source, not from the text. A structured field, a post URL, a package homepage,
a catalog's outbound link. Text mining is where the junk enters: on the first pass over job feeds about half of
the extracted domains were the board itself, an ATS (greenhouse.io, lever.co, ashbyhq.com) or a link inside the ad
rather than the employer.

2. The host answers and looks like a company. Every candidate is requested live and kept only if the page
carries product signals — pricing, sign-up, demo, contact. On the SaaSHub pull this pass took 909 candidates down
to 351 usable rows. Without it the file fills with university course pages, docs sites and parked domains.

3. The address belongs to the domain it sits on, then it is checked. Domain match first, SMTP check second.
On one agency pull two addresses out of thirty-five were placeholder text and three belonged to a different
domain than the page they sat on — five rows that would have shipped as working data.

Underneath all three sits deduplication: 45 sources produced 6,955 rows and 6,955 unique root domains, no
duplicates and no row without a domain. Subdomains are folded into their root (app., shop., blog.) unless
the root is a platform — then the candidate is dropped.

Why the honest yield is 15% and not 100%

Because 1,040 addresses come from the companies themselves, not from a purchased database or a guessed pattern.
The rest of the rows are still useful: they are companies with a live site, a product and a hiring signal, and
their mailbox is a phone call or a form away. What they are not is a send queue.

That distinction is the reason the first test in the engagement is 100 verified contacts rather than a
monthly volume. A strict two-variant test needs 13,914 contacts per arm — 56 days at 500 a day. Below that
volume, the honest output is not a conversion rate; it is a reading list: which segment answers, which sentence
earns a reply, which objection comes back first.

Scopes, published: $900 Sprint (segment, checked rows, first touches), $1,900/month Engine (the loop keeps
running), $2,900 Full Build (offer, landing page, free tool, distribution). The arithmetic behind the numbers is
on the site: https://axelfreeman.com/b2b-data-enrichment-service.html

If you are staring at a file you already bought, the useful question is not "how many rows" but "how many of
these rows would survive the three checks". Usually about a third do not — and that is the finding, not a
failure.

Top comments (0)