enrichment-arbiterdynamic waterfall router
data enrichment · vendor routing engine

buy the verified hit,
not the call.

a self-hosted router that decides which data vendor to ask first. it caches, ranks by cost per verified hit, verifies before trusting, caps the spend, and learns from bounces.

the one number: ECPVH — effective cost per verified hit. the expected dollars to walk away with one working email or phone, not one API response.
view code on github ↗

python · sqlite · httpx · 11 tests · status ready

01what it is

a decision layer for enrichment spend. it does not own a people database; it orchestrates the vendors that do, and keeps the money and the trust under control.

a router, not a database

it asks apollo, hunter, prospeo and friends in a learned order and stops at the first verified answer.

cost-aware by default

ranking is driven by cost per verified hit, with per-call budget gates and a negative cache so unfindable leads don't re-burn credits.

it learns from reality

every call is logged. downstream bounces retroactively penalize the vendor that produced the bad address.

what it is not: not a crm, not a sequencing tool, and not a black box. it returns a record plus a full waterfall trace: which vendors were tried, what they cost, and why the winner won.

02how it works

one request, seven decisions. every failure is a value, never a crash.

1 · request
normalize
strip schemes and paths; hash the identity into a cache key.
2 · cache
serve or skip
fresh positive or negative hit returns at $0.00.
3 · rank
score the field
active vendors ordered by routing score for this task and segment.
4 · explore
5% shock
occasionally promote a lower vendor to slot one, to rediscover it.
5 · call
budget + breaker
pre-check the dollar cap; isolate 429/5xx vendors for 15 minutes.
6 · verify
trust nothing raw
syntax + mx today, swappable for a paid verifier.
7 · learn
log + recalc
scores update lazily; bounces arrive later and change the ranking.

03the math that matters

three ideas do most of the work: cost per verified hit, priors that stop tiny samples from lying, and a score that trades yield against cost and latency.

effective cost per verified hit ECPVH = costattempt + MatchRate × costmatchMatchRate × AccuracyRate
composite routing score S = w1(MatchRate × AccuracyRate) − w2(ECPVH ÷ maxCost) − w3(p95 ÷ maxLatency)
bayesian priors

assume 4 matches in 10 attempts and 3 verified among 4. a vendor has to earn its reputation with volume.

cold-start floor

tried but zero verified hits? the score floors to −999 and it sorts last, still reachable by explore.

epsilon-greedy

95% exploit the best-known order, 5% promote a lower vendor so a quietly improved one gets found.

bounce penalty

a bounce is worse than a miss: it wastes a send and hurts deliverability. each bounce subtracts two.

circuit breaker

3 consecutive 429/5xx/timeouts and the vendor cools down for 15 minutes. any 2xx resets it.

p95 latency

the tail matters. latency is measured over the last 100 calls and normalized against a cap.

honest small-sample note: with very little history, one slow success can rank below an untested vendor. that is deliberate conservatism, not a bug. it settles as volume arrives.

04proof

measured, not claimed. the repository ships the engine and generic adapters; keys, real run data and customer lists stay private.

$0.02
estimated cost of one verified hunter hit
$0.00
cost of the same lookup, served from cache
2,391 ms
latency of that live call
11
offline tests, no network, no spend
one real run, end to end

a hunter lookup for a person at a large public company returned a work email, passed mx verification, and was logged with cost and latency. the address is redacted here.

and then it cost nothing

immediately repeating the lookup returned cached: true, total_cost: 0.0, and zero api calls. the negative cache does the mirror trick for unfindable leads.

the safety rules are tested, not hoped for: budget cutoff, positive and negative caching, the breaker tripping and recovering, bounce feedback dropping a vendor's score, zero-division math, and the golden-probe money gate.

05the decisions that matter

verify before trust

a vendor saying "here is an email" is not the same as an email that can receive mail. the gate runs before the value is accepted.

budget before the call

the worst-case cost is checked before dialing. a skipped vendor never becomes a negative cache lie.

fail-safe, not fail-open

timeouts, 429s and vendor json become clean results. a missing key is a skip, not a fake failure.

logs are the source of truth

scores are derived from an append-only log, so every ranking can be explained and rebuilt.

one owner per data point

the cache remembers which vendor won, and feedback can blame the exact call that produced a bad value.

per task, per segment

a vendor can win us mid-market tech and lose eu enterprise. the scoreboard is sliced accordingly.

python 3.11+ sqlite + wal httpx async adapters pydantic v2 dns mx verification cli-first no daemon