Workflow Engine · ac-python-api · Intelligence DB

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.

Entry enrich_company()Waterfall cache → cheap → structured → webCost of a hit $0Write-back provenance-tracked
Resolved domainCache lookupWaterfall on miss·Write back · serve
00

What enrichment does

Discovery (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.

4
Waterfall tiers
cache → cheap → structured → web
$0
Cost of a cache hit
vs ~$0.05-0.40 per chain
Enrichment per company
across all tenants
3
Provider categories
firmo · contact · technographic
KEYEnrich once, serve everywhere

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.

01

Data flow

How 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.

1234
Cache hit

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.
WHYOne miss pays for every later hit

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.

02

Cache-first read

The 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.

$0provider spend
0provider calls
cacheserved as-is
WHYTTL tiers keep the hot path free

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.

03

Enrichment waterfall

On 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.

Tier 0 · deterministic

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.

free
Cost
per company
inherited
Reputation
provenance weight
WHYStructured beats web on conflict

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.

04

Provider categories

Tier 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.

In production

Running today

  • Explorium - Structured firmographics; the highest reputation tier in the waterfall.
  • Parallel - Structured research and enrichment for gap-fill.
Vetted candidates

Recommended next

  • People Data Labs - 70M+ company profiles; firmographic and employment data via API.
  • Coresignal - Firmographics plus headcount-trend data, deduped at source.
05

Privacy boundary

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).

Global intel layerno org_idRLS deny-all · service role only
intel_companiesintel_company_factsintel_sources
Enriched public facts, with provenance

Every fact the waterfall resolves flows up into the shared layer, tagged with source and confidence.

Cached profile pre-fills the tenant row

The public-fact profile pre-fills crm_companies_v2 enrichment fields at save time.

CRM stage, owner, notes, lead score

Tenant judgement and workflow state never enter the shared layer, even aggregated.

Tenant layerorg_id + RLS per org
crm_companies_v2workflow_run_companiesnotes · tasks · outreach
Written back to the shared layer
  • Firmographics: industry, size band, locations, founded year
  • Funding rounds, IPO status, acquisitions
  • Website content, positioning, tech stack
  • Verified work emails and public contact data
Never written back
  • 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
ToSOne gate before write-back ships

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.

06

What enrichment writes

Three 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 fills
domaintext · uniquenormalized, primary identity key
name · website · description · logo_urltext
industry · sub_industrytext
employee_count_bandtext
funding_total_numeric · latest_funding_round · ipo_statusnumeric / text
tech_stacktext[]
extrajsonblong-tail provider fields until usage earns a column
last_enriched_attimestamptzdrives the TTL tiers
1

Structured provider payloads (Explorium, Hunter)

highest confidence, contractual accuracy

2

First-party scrape of the company website

public and current, less structured

3

Web-inferred (GPT web_search)

lowest confidence, never overwrites a higher rank silently

See the company intelligence database for the full storage architecture and read-through cache design, and Company Signals for the discovery and scoring pipeline this enrichment step sits inside.
AgencyCore · Company EnrichmentWorkflow Engine · intelligence DB