Skip to main content
SCRAPERS & DATA

Finds the right companies and drafts the first email

Pluggable discovery sources, website enrichment, dedup and two-axis scoring, then a drafted email a human reviews and sends.

THE PROBLEM

What was in the way

Finding companies worth partnering with is slow, and almost none of it is judgment. Someone searches a trade in one city, opens every result, hunts for a contact address, checks whether the firm is certified and still trading, then writes a first message specific enough to be worth answering.

One city is an afternoon. A whole country is not work a person finishes, so it gets done thinly or not at all.

THE APPROACH

How it was built

Five stages that each run on their own: discover, enrich, score, draft, export. Discovery sources sit behind one interface as drop-in adapters, and records merge on registrable domain, then phone, then name and postcode.

Ranking splits into two scores that usually get collapsed into one: whether the record is complete and the firm legitimate, and what the firm is worth if they convert.

Scope stops at the draft. There is no send path in the codebase, and every draft passes a written-rules lint before a human reviews it.

Discovery to reviewed draft
Discovery to reviewed draft
HIGHLIGHTS

How it works

Two scores, not one

Lead quality and worth if they convert stay separate columns in the export, so neither hides the other. High value with no email address moves to a call list instead of being dropped.

Nothing suppressed reaches a draft

Competitor domains, out-of-scope firms and the do-not-contact list are applied before drafting, not at send time. Crawls honour robots.txt and prefer role addresses over personal ones.

Drafts are linted before a human sees them

Formal register, no percentage claims, no unfilled placeholder tokens, no certification claimed that the sender does not hold. A draft that fails the lint is flagged for review, never listed as ready.

RESULTS

What it does now

never sendsno send path in the codebase, a human sends every email
3,534 companiesdeduped from 8,193 raw hits in one national run
runs with no API keydeterministic drafter fallback, lint clean by construction
STACK

What it is built on

Pythonasync pipeline and CLI
SQLitesource of truth store
httpxrobots-aware HTTP client
Pydantic v2typed records and config
Claudeemail drafting
selectolaxemail and cert extraction
tldextractregistrable-domain dedup

Got something in your workflow that looks like this?