Enriching Salesforce is not a one-time import. It is a loop.
A Salesforce record starts decaying the moment it is saved. People change jobs, companies move, headcounts grow, phone lines get reassigned. Roughly 3 to 5 percent of CRM records go stale every month, so a database left alone for a year is wrong about a third of the time. Most teams treat enrichment as a project: buy a vendor, run one backfill, declare victory. Two quarters later the fields are stale again and reps stop trusting the data enough to act on it.
The teams that win run enrichment on a schedule, verify every value before it touches a record, and only write data they have actually checked. This is how to build that loop in Salesforce.
What you need before you start:
- A Clay account connected to your Salesforce instance: Ideally with a sandbox alongside production.
- Admin or RevOps permissions: Enough access to map fields and add a custom field or two.
- A short list of the fields that matter: The ones that actually change who a rep calls and what they say. Enrich those. Skip the rest, because every field you enrich spends credits.
Step 1: Pull the right Salesforce records into Clay
Start narrow, not with the whole org.
Clay's native Salesforce integration imports objects directly, with no CSV exports that go stale the day you run them. You authenticate once (a Salesforce user signs in via OAuth, or you use client-credentials for a server-to-server connection), then pull Leads, Contacts, Accounts, or Opportunities into a Clay table. If security is a concern, connect through a restricted Salesforce user with field-level limits: it can still write approved enrichment back without exposing your whole CRM. When you need a precise slice, a Salesforce SOQL source lets you query exactly the records you want.
The instinct is to import everything. Resist it. Build a filtered Salesforce view first, accounts in an active deal, contacts missing a verified email, leads from last quarter with a blank company size, and import that view, not the database. Carry over the Salesforce Record ID on every row. It is the key that lets you write enriched values back to the exact right record later, with no ambiguity about which Jordan Lee at which account you mean.
Step 2: Find which fields are empty, and which are quietly wrong
A blank field is an honest problem. A field that looks full but is three years out of date is the expensive one.
The decay is invisible until someone measures it: years of records that nobody has touched since the day they were entered, with lead routing, scoring, and ad audiences all quietly inheriting the drift. So measure it before you enrich anything. Profile the records you imported and separate true gaps from silent decay, because the two need different treatment.
Auto-plays one accurate record decaying over 18 months. Click any month to pause and see what changed.
Jordan Lee
5/5
Fields still accurate
0%
Record decay
A Salesforce record is not static data; it decays on a predictable schedule, and the field that mattered most is usually the one that went wrong without anyone noticing.
The pattern sets your priorities. Time-sensitive fields like title, employer, and phone need frequent refresh. Slow-moving firmographics like founding year, industry, and HQ city can be enriched once and left alone. Enrich on each field's real decay rate, not on one calendar reminder.
Step 3: Waterfall-enrich the gaps with verified data
One provider is a coverage ceiling. A waterfall is how you get past it.
No single vendor has every contact and every firmographic. The provider that nails North American work emails may be blind in EMEA; the one with deep firmographics may carry no direct dials. A waterfall checks the cheapest, highest-hit provider first, and only falls through to the next when the first returns nothing, until a field fills or the chain runs out. You pay for the provider that delivers, not the ones that whiffed.
Auto-runs a cheapest-first work-email waterfall to 91% where one provider stalls at 58%. Click a provider to inspect it.
Stacking providers cheapest-first lifts usable coverage far past any single vendor's ceiling while billing each provider only against the records the one before it missed. Providers and ordering reflect Clay's North America work-email data-test; order your own chain to your segment.
That coverage lift is the difference a waterfall makes against a single incumbent vendor.
share of its data gap Hex filled with Clay's waterfall, versus its previous single enrichment vendor
Read the full storyFor the gaps a provider database cannot fill, the company-specific facts that decide your deals, point an AI research agent at the record. Claygent reads the open web and returns a structured value you can write to a field: whether an account runs the platform your product integrates with, whether they just opened an office in a territory you cover, whether they posted a role that signals the project you solve.
Company: {{Account Name}}Domain: {{Website}}Research this company using its website, recent press, and publicjob postings. Return ONLY a JSON object, no prose:{ "employee_count_estimate": <integer or null>, "primary_industry": "<one of: SaaS, Fintech, Healthcare, Manufacturing, Other>", "uses_salesforce": <true | false | null>, "recent_funding": "<round and date, or null>", "evidence_url": "<the single URL that best supports the above>"}If a value cannot be confirmed from a credible source, return nullfor that key. Do not guess. Do not infer headcount from followercounts or unrelated pages.
The "return null, do not guess" instruction is the load-bearing part. An enrichment that admits it does not know is worth more than one that confidently invents a number you then write into your record of truth.
Step 4: Verify before you write anything back
Coverage is not the same as usable coverage. The gap between them is bad data.
A found email is a string. A verified email is a string an inbox will actually accept. Write the unverified version into Salesforce and the first three bounces teach reps to double-check every field by hand, which defeats the entire point of enriching. The fix is not more data. It is a single gate that decides what is true before anything reaches the record.
Auto-runs four enriched values through the gate. Click any card to see why it wrote, held, or went to review.
Incoming for Jordan Lee
deliverability → valid mailbox
line status → disconnected, number reassigned
conflict vs stored 'Senior PMM' → job-change detected
confidence → high
Written: 2 · Held: 1 · Review: 1
The gate's job is to write fewer values, not more: a verified, high-confidence value updates the record, while a failed or conflicting one is held so it never overwrites something a rep trusts.
Encode that trust hierarchy in your write logic so a high-confidence enrichment never clobbers a rep-verified value, and exclude manually maintained fields, deal notes, custom scores, relationship context, from automated updates entirely. Overwriting a rep's institutional knowledge with a vendor's guess is the fastest way to kill adoption.
Step 5: Write clean values back without creating duplicates
The write-back is where good intentions create messes, so use the right action for what you hold.
Because you imported records carrying their Salesforce Record ID, the correct write is the Update record action, which takes the Record ID as its key and lands on that exact record. Turn on Ignore blank values so a missing enrichment never wipes a field that already has data. You will not create duplicates, because you are updating a known record rather than creating one. Two related actions cover the other cases: Create record, which Clay configures to prevent duplicates by default, for net-new rows; and Upsert, which creates-or-updates in one step but requires an external ID on the object, for when you key on your own identifier instead of the Salesforce Record ID.
Auto-maps fields, then shows why matching on the Record ID prevents duplicates. Click a row to inspect its write behavior.
Updating on the Salesforce Record ID lands every enriched value on the exact existing record with zero duplicates, while Create prevents duplicates by default and Upsert is the path only when you key on an external ID.
Test the whole mapping against your Salesforce Test Env sandbox before it touches production. A sandbox mirrors your setup against throwaway data, so you can confirm the right fields update on the right records first. Treat the first production run like a release, not an experiment, because a Salesforce write cannot be undone.
Step 6: Put the loop on a schedule so the data stays fresh
A one-time backfill is a snapshot of a moving target. The schedule is what makes enrichment hold.
The mechanism is a Salesforce list that maintains itself. Add a custom field, Last Enrichment Date, and build a dynamic list filtered to records where that date is older than your chosen window. Records aging past the window join the list on their own; records you just refreshed drop off on their own. Clay imports that list on a schedule, runs the same waterfall-and-verify workflow, writes the verified values back, and stamps the date so each record leaves the queue until its next cycle. Nobody has to remember to run anything.
Scope the refresh, because credits follow the work. Every enrichment spends Actions for the orchestration on each row, and provider results spend Data Credits, so contacts in active deals and target accounts earn a tighter window than closed-lost or do-not-contact records, which you can exclude from the loop entirely. That scoping is the difference between an enrichment project and an enrichment engine: the project ends, the engine keeps the database honest.
“Clay has become the orchestration layer for everything GTM. Salesforce for record-keeping, Snowflake for product data, and Clay for turning it all into automated action.”
When the loop runs, coverage climbs and stays climbed instead of sliding back.
enrichment coverage Vanta holds across its CRM contacts after moving to Clay's continuous waterfall
Read the full storyCommon failure modes, and how to avoid them
Most enrichment loops fail in predictable ways. Watch for these.
- Enriching everything instead of what reps use: Importing the whole org and filling every field spends credits on data nobody acts on. Filter the Salesforce view before the import, and enrich only the fields that change who gets called and what gets said.
- Writing unverified values straight to Salesforce: A found email that bounces costs more than a blank one, because it trains reps to distrust the whole CRM. Route every value through the verify gate first, and hold anything that fails or conflicts.
- Overwriting rep-verified and manually maintained fields: A vendor guess that silently replaces a rep's deal notes or a corrected title destroys trust fast. Encode a trust hierarchy and exclude manually maintained fields from automated updates.
- Using the wrong write action: A repeated Create with no match logic is how duplicates appear. For records you imported, use Update record keyed on the Salesforce Record ID; reach for Upsert only when you key on an external ID. Turn on Ignore blank values so empty enrichments never overwrite good data.
- Running it once and calling it done: A backfill decays at 3 to 5 percent a month. Without the dynamic list and the scheduled refresh, you are back to stale data within two quarters. The loop, not the backfill, is the deliverable.