DEV Community

Axel Freeman
Axel Freeman

Posted on Originally published at axelfreeman.com

Your B2B list is worth its address share, not its row count

A 10,000-row list is not 10,000 chances to get a reply. It is however many of those rows publish an address on their own domain — and that second number is a property of the source, not of the file. We keep a working file of company domains and count that share for every source family we pull from. Here is what it looks like after 9,756 domains, 1,714 public addresses and one honest question: where did the domain come from?

Two ways to get a domain, and only one of them is clean

A domain can be read out of text where someone mentioned their company, or read out of a field the company itself filled in a directory. The second one is cleaner by construction.

On a job board the domain has to be dug out of the vacancy body. Roughly half of those attempts land on the job board itself, on a recruiting platform, or on a company already in the file. On an application marketplace or a package registry the domain is a named field filled by the vendor, and the reject rate drops to single digits.

Our largest single pass came from an application marketplace: 3,000 applications → 2,377 new domains → 1,798 live sites with product signals (76%) → 1,538 rows kept (65%). The filter that did the cutting was not a blacklist but a product test: pricing, a sign-up, a demo request, integrations. Documentation sites, personal pages and framework homepages go out there.

The field that gave the domain gave nothing else

Those 1,538 rows came with an address share of zero. The field is a website, not a contact. We had grown the file by 1,538 rows and the number of sendable rows by nothing at all — which is exactly the trap of measuring a campaign by file size.

So we stopped counting domains and started walking sites.

300 "contactless" rows, walked

We took 300 rows with no address and opened the pages companies publish for contact: home page, /contact, /about, an imprint page where the law requires one. Only addresses whose domain matched the company's own domain were kept.

Step Result
Rows walked 300
Domains with a published address on their own site 172
Kept after the address-to-domain rule 169
Answering MX 169 of 169
Spot-check against the live page 4 of 4 confirmed

A source that looks contactless at intake is more than half contactable if you read the pages the company actually maintains. The three rejected addresses are the other half of the rule: one mis-split token and two strings that only looked like addresses in raw HTML. They were dropped, not repaired. An address that has to be guessed is not a contact.

Yield by source family

Where the domain came from Domains taken Live with product signals Rows kept Publish an address
Application marketplaces (vendor-filled external_url) 3,000 1,798 (76%) 1,538 (65%) 0% at intake → 56% after walking contact pages
Agency directories 59 hosts per pass full pass 492 ~60%
Package registries (projectUrl, homepage_uri) 3,821 140 (29%) 140 ~15%
Repository homepage (GitHub repos and orgs) 2,429 553 553 ~11%
WordPress.org (plugin homepage, theme author URL) 9,785 600 of 695 themes 486 plugins + 490 theme authors ~34% for theme authors
Job-description text (boards, "who is hiring") ~1,100 vacancies 8 of 16 confirmed half the rows never reach the contact step

Theme authors sit in between, and for a reason: 8,695 themes in the WordPress.org directory resolve to 729 unique author domains, and a theme shop is a company selling a product, so it publishes pricing, support and a contact page — 600 of 695 answered, 490 were kept, and a third of those handed over an address.

That table is the whole argument. A vendor who sells you 10,000 rows is selling you the left column; the column that decides whether the list is work or decoration is the right one. At 11% the same file is 1,100 addresses, at 56% it is 5,600.

How each row is counted

  1. Domain from a filled field. No row enters without a domain that belongs to the company and a URL where it was published.
  2. Live site with product signals. A 200 is not enough: pricing, sign-up, demo request or integrations must be present.
  3. Address matched to its own domain. A role address on someone else's domain is not a contact for that company, however it appeared on the page.
  4. MX before sending. Every address domain answers MX; the ones that do not are marked, not hidden.
  5. The reject reason is kept. Removed rows stay in a reject file with the reason, which is how the numbers above can be checked.

Three questions for a list vendor

  • What share of rows publish an address on their own domain — not "has a contact field"?
  • How many domains answer MX, and what happened to the ones that did not?
  • Which addresses came from a field the company filled, and which were assembled by a tool?

A vendor who cannot answer the third question is selling the 0% column. Building the file is not romantic work; it is counting, and then walking the pages.

The full method, the checks and the numbers are on the site: The address is the only number that matters in a B2B list — that page also carries the six list checks and the pre-send audit, in case your file is fine and your sending is not.

Top comments (0)