Customer story · Data Quality & Enrichment

A repeatable list-import pipeline: normalize, domain-match, waterfall the email, then hand it over

Every event produced a spreadsheet in a different shape and marketing was hand-researching names to make lists loadable. We built a duplicated-template enrichment pipeline in Clay with the company domain as the dedupe key and a validated email waterfall, then retired direct CRM writes in favour of a single dedupe authority — and handed the whole thing to the client's own coordinator.

ProofWhat happened on a real engagement.
Fintech & Financial ServicesSector
Late-stageStage
Ongoing engagementDuration
5Min read

Anonymized. The company is described by sector and stage only — no customer is named, and quotes are attributed by role.

#The challenge

Conference, webinar and field-event lists arrived in whatever shape the organiser handed over — sometimes an email address and nothing else, sometimes a name with no company, job titles written a dozen different ways. Marketing was manually looking people up to fill in first names before a list could be loaded at all. The batch data provider they would normally lean on was effectively rationed because credits were being consumed elsewhere, so 'just run it through the provider' was not available. Lists that did get loaded created duplicate accounts, and records regularly landed with no campaign membership attached — which makes an event look like it produced nothing.

#The approach

One template table, duplicated per event

A master event-processing table lives in a shared workspace folder and is duplicated for each new list, with completed runs nested underneath so any past event can be reopened and audited. Input columns are colour-coded so a non-technical operator knows exactly which fields to paste and which are generated.

Normalize before you enrich

Full name is derived from first and last rather than trusted from the source. Job titles from badge scans and registration exports run through an AI normalization step, because event titles are close to free text and inconsistent titles poison every downstream persona filter. Two mandatory marketing fields — primary and secondary lead source — are stamped at intake, so attribution is captured at the point of entry instead of being reconstructed later.

Make the company domain the match key, not the company name

The pipeline resolves company name to a domain first, and the domain is what gets checked against the CRM to answer 'does this account already exist, or is this net-new'. This is the dedupe control for the entire operation. The related company-lookup table had the same failure in reverse: loose name matching returned multiple candidate records per company until fuzzy-match logic was tightened so a lookup resolves to a single accurate record.

Enrich the company, then decompose the address

The resolved domain drives a company enrichment — size, type, employee count, industry, full address — and the address is split into street, city, state and postal code as a distinct step. Unglamorous, and it is the difference between a CSV that loads into the CRM cleanly and one that needs manual remapping on every run.

Waterfall the email, then override the waterfall on purpose

Person email is found by a waterfall: enrichment providers stacked in priority order, first hit wins, then a validation step checks the address is actually in use. The waterfall by default only forwards addresses that pass validation, which silently blanks rows where an address was found but failed verification. We added a separate aggregate 'final' column that deliberately overrides the valid-only default, so a found-but-unverified address still reaches the CRM flagged as such — a rep can decide what to do with it, whereas an empty field tells them nothing.

Put the expensive lookups last

Profile URL (via an AI-assisted lookup step) and phone number run at the end of the table, after the domain and email gates, so per-row cost is only incurred on rows that survived. Lookup costs were compared explicitly for the client — a native provider enrichment, a search-based step and an agent step each carry very different per-row credit costs for the same field — so the team could choose the cheapest acceptable path per field rather than defaulting to the richest one.

Stop writing to the CRM from three places

The pipeline originally pushed directly from the enrichment layer into both the CRM and the marketing platform. That was retired. The enrichment layer now exports a cleansed CSV which is loaded through the dedupe and routing tool that already owns matching and assignment, and that tool writes onward to both systems. One dedupe authority instead of three competing ones, and the CSV column structure was renamed and consolidated to drop cleanly into it without a manual remap on every upload.

Treat the campaign-attach failure as its own bug class

The recurring break was never the enrichment — it was the merge field carrying the CRM record ID back into the table. When it failed to populate, the run stalled part-way through and leads and contacts synced without campaign details attached, so the event showed no pipeline. This was ticketed separately each time with a re-run and reconciliation procedure rather than being absorbed into 'the table is flaky'.

Hand the table over rather than owning it

The whole flow was walked end-to-end live with the client's incoming coordinator and recorded, including the practice of running the first five rows to see the credit estimate before committing a full list. The template, the nested archive of past runs and the walkthrough were the deliverable — not a standing dependency on us to run every event.

#Outcomes

A pipeline a new hire can run

Duplicated-template model plus a recorded end-to-end walkthrough; the client's newly hired coordinator took over event list processing.

Dedupe consolidated into a single authority

Direct enrichment-to-CRM writes were retired in favour of a CSV export through the existing dedupe and routing layer, with the export column structure rebuilt so it maps without manual intervention.

A cheaper enrichment path under a constrained data budget

A stacked waterfall replaced dependence on a rationed batch provider, with per-field lookup costs compared side by side so the team could trade cost against completeness deliberately.

Failure modes documented rather than tolerated

The merge-field/campaign-attach break and the loose company-name matching were each isolated and fixed as named defects. No conversion or pipeline lift was measured on this workstream — the deliverable was the pipeline and its handover.

In their words

What the customer said

“I'd love to remove all the duplicates and make sure that everything mapped to the right thing, but that's difficult.”
Connected

In the knowledge graph

Every entity below has its own page, aggregating what we measured, what we recommend and what guests said.

Related

More on these topics