Company Enrichment
Company enrichment is the step that turns a resolved domain into a complete, trustworthy profile. It reads the global intelligence cache first, runs a fixed-order provider waterfall only on what is missing, and writes every resolved fact back with provenance - so the first org to enrich a company pays once and every later search rides free.
What enrichment does
tl;drDiscovery (Company Signals) finds a company worth contacting and resolves it to a canonical domain. Enrichment fills the firmographics, contact and technographic facts that profile needs - cheaply, and only once across all tenants. It is a cache-first read in front of the company intelligence database: a fresh hit costs nothing, a miss runs the waterfall and writes back with provenance.
Company facts are slow-moving, so they are worth caching - unlike signals, which are perishable and always re-discovered live. Enrichment treats the intelligence DB as the first, free rung of the waterfall: the expensive part of learning a company is paid once, written back with provenance, and reused by every later search at $0. The waterfall only ever runs on what the cache is missing or has let go stale.
Data flow
interactiveHow a single enrich_company() call moves through the system. Pick a path - a cache hit, a miss that runs the waterfall and writes back, or a stale-serve - and the diagram lights the nodes and edges it touches, in order. Click any node for detail.
Fresh hit: the facade finds an in-TTL profile in intel_companies and serves it straight into the result and the tenant pre-fill. Zero provider calls, $0 spend.
Click any node for detail. The write-back path is what turns a per-org cost into a one-time cost: the first tenant to touch a company runs the waterfall, the result lands in intel_* with provenance, and every later run by any tenant follows the cache-hit path at $0. The pre-fill into the tenant CRM is one-way by construction - nothing tenant-derived ever travels back up.
Cache-first read
interactiveThe core mechanic: enrichment asks the intelligence DB first, the waterfall runs only on a miss, and every miss makes the cache smarter. Pick a scenario and watch the lookup path.
Field groups age at different speeds, so freshness is checked per field group, not per record: hot signals (~7 days), warm funding and headcount (~30 days), cold firmographics (~180 days). A lookup never blocks on a refresh - stale data is served immediately and a background job re-runs just the expired tier.
Enrichment waterfall
interactiveOn a miss the waterfall runs in fixed order - cache, then cheap search, then structured providers, then web fallback. The model never reorders tiers; its only decision is escalate-or-stop against a completeness target, so the run stops the moment the profile is good enough. Pick a tier to inspect it.
Intelligence DB cache Hit: skip all paid tiers
A global company-facts cache keyed by normalized domain, TTL per field group. A hit returns firmographics instantly and skips every paid tier - the cross-org payoff where the first org to enrich a company pays, and every later search rides free.
Every resolved field carries the reputation of the tier that produced it. When two tiers disagree, the higher reputation wins - a structured provider value is never silently overwritten by a web-inferred one, and an unverified web value is stored low-reputation so it caps its own contribution to the downstream lead score.
Provider categories
interactiveTier 2 is a registry of structured enrichers grouped by what they fill. Each is an enricher, never a signal source - discovery never calls them. Pick a category to see what runs in production today and the vetted candidates that would close its gaps.
Durable company facts - industry, size band, HQ, revenue, founded year.
Running today
- Explorium - Structured firmographics; the highest reputation tier in the waterfall.
- Parallel - Structured research and enrichment for gap-fill.
Recommended next
- People Data Labs - 70M+ company profiles; firmographic and employment data via API.
- Coresignal - Firmographics plus headcount-trend data, deduped at source.
Privacy boundary
seam Enrichment is the main writer into the shared layer, so the seam matters most here. It is enforced twice: by policy (only externally observable, public facts may be written back) and by mechanism (client roles get RLS deny-all on intel_*; the ac-python-api service role is the only door).
intel_companiesintel_company_factsintel_sourcesEvery fact the waterfall resolves flows up into the shared layer, tagged with source and confidence.
The public-fact profile pre-fills crm_companies_v2 enrichment fields at save time.
Tenant judgement and workflow state never enter the shared layer, even aggregated.
crm_companies_v2workflow_run_companiesnotes · tasks · outreach- Firmographics: industry, size band, locations, founded year
- Funding rounds, IPO status, acquisitions
- Website content, positioning, tech stack
- Verified work emails and public contact data
- CRM stage, owner, notes, tasks, outreach history
- Whether any tenant saved, rejected or shortlisted a company
- Per-tenant ICP scores, lead scores, fit judgement
- Anything derived from tenant activity, even aggregated
Caching paid provider output cross-tenant must be cleared against each provider's terms (Explorium and Hunter in particular). Scraped and web-derived facts are unambiguous; structured provider payloads need that review before write-back is enabled for them.
What enrichment writes
modelThree tables carry the output. The profile is the fast read path the next run hits; facts and sources keep that path honest - every claim is explainable through its source and revocable in one delete. Click a table.
intel_companiesCanonical profile - the fast read path enrichment fillsdomaintext · uniquenormalized, primary identity keyname · website · description · logo_urltextindustry · sub_industrytextemployee_count_bandtextfunding_total_numeric · latest_funding_round · ipo_statusnumeric / texttech_stacktext[]extrajsonblong-tail provider fields until usage earns a columnlast_enriched_attimestamptzdrives the TTL tiersStructured provider payloads (Explorium, Hunter)
highest confidence, contractual accuracy
First-party scrape of the company website
public and current, less structured
Web-inferred (GPT web_search)
lowest confidence, never overwrites a higher rank silently