Clay logo, go to homepage

How to keep your CRM data fresh automatically

Stop CRM decay with a loop that monitors job changes, re-enriches on a schedule, and verifies before overwrite. Here is how to build it in Clay.

May 9, 202610 min read

A CRM is never clean once. It decays the day you stop touching it. The reason is not your reps or your import process. It is the world moving. People change jobs, companies relocate, two accounts merge under a new name, and the contact who championed your last deal leaves for a competitor. None of that shows up as a blank field. It shows up as a field that still looks full and is now wrong, which is the expensive kind. The win is not a one-time cleanup; it is a maintenance loop that runs on its own, detects decay, and refreshes the records that rotted before a rep opens them. That loop sits on top of HubSpot or Salesforce without changing your system of record. This is how to build it.

What you need before you start

  • A connected CRM.: A Clay account connected to your CRM through the native HubSpot or Salesforce integration, not CSV exports, which go stale the moment you run them.
  • A filterable refresh-date field.: A custom field your CRM can filter on, named something like Last Enrichment Date, that Clay will stamp. This is different from the built-in Last Modified Date.
  • A LinkedIn URL on every record.: The job-change monitor matches on each contact's LinkedIn URL, not on a CRM ID, so the URL has to be stored on the record.
  • A shortlist of fast-decaying fields.: The fields that change who gets called and what gets said: title, employer, direct phone, email, headcount. Those are worth a refresh schedule. Slow-moving firmographics like founding year can be enriched once and left alone.

This guide is about the recurring freshness loop. Filling fields that have never had a value is net-new enrichment, covered in the guide to enriching Salesforce records. Reconciling fields that disagree with each other is standardization, covered in the guide to cleaning and standardizing CRM data. Here, the records are already in your CRM and already had good values. The job is keeping those values true over time.

Step 1: Measure how fast your CRM is actually decaying

Decay is not a vague worry; it is a rate you can put a number on, and the number decides your whole cadence.

Roughly a third of B2B contact data goes stale in a year as people move and companies change shape. The average is a trap, because decay is not evenly spread. Title and employer rot fastest. Direct phone follows when a number gets reassigned. Industry, HQ city, and founding year barely move. Refresh everything on one calendar reminder and you overspend on the slow fields while under-refreshing the fast ones. Before you build anything, profile your records and sort each field by how quickly it loses accuracy, not by how empty it looks today.

Play 12 months forward and watch which fields rot first

Month 0 / 12

Priya Nair, Head of RevOps at Brightwave

TitleHead of RevOps
CompanyBrightwave
Work emailpriya@brightwave.com
Direct phone+1 415 555 0188
Headcount320
Founding year2014
Fields still true 6/6Record now misleads a rep no

Founding year, HQ city, and industry move rarely and can be enriched once and left alone. The blanks were never the problem; the fields that still look full and have quietly gone wrong are.

Decay is not uniform, so the right refresh cadence is per-field: title and employer rot in months while firmographics barely move, and the field that goes wrong is rarely the one that goes blank.

The fields that flip red early are your high-frequency refresh list. The ones that stay green for a year get a light touch or none. Set the cadence to the field, and you spend on the fields where decay actually happens.

Step 2: Build a dynamic refresh list that fills and drains itself

A static list of records to refresh is stale the moment you save it. A dynamic list is the only version that maintains itself.

The mechanism lives in your CRM, not in a spreadsheet. Create the Last Enrichment Date custom field, then build an active or dynamic list, named something like "Contacts Due for Refresh," filtered on that field being older than your chosen window. A record that ages past the window joins the list on its own. A record Clay just refreshed gets its Last Enrichment Date stamped and drops off on its own. Nobody curates the queue, because the queue is a filter, not a file. Layer in priority so your most important records get the tightest window: contacts in active deals, high lead scores, and target accounts refresh often, while closed-lost and do-not-contact records can be excluded from the loop entirely.

Drag the refresh window and switch the priority filter to reshape the queue

1,500contacts due for refresh, of 2,000 eligible
Due now Eligible, still fresh Excluded from the loop

Records older than the window queue themselves; records Clay just refreshed get a fresh stamp and drain out. The queue is a filter, not a file.

Last Enrichment Date is a custom Clay-stamped field, distinct from the CRM's built-in Last Modified Date.

A dynamic list filtered on a last-refresh date is self-maintaining: records queue themselves as they age in and drop off as they are refreshed, so the queue never needs hand-curating.

Clay imports that dynamic list directly through the native integration, mapping the CRM record ID, email, name, the contact's LinkedIn URL, and the Last Enrichment Date field. Two identifiers do different jobs here. The LinkedIn URL is what the job-change monitor in Step 3 matches on. The CRM record ID is what every refreshed value writes back to in Step 6, so the update lands on the exact right record.

Step 3: Monitor job changes, the single highest-value freshness signal

Of every field that decays, one is worth building the whole loop around: where your contact works.

A job change is not just a stale field to repair; it is a buying signal in disguise. When a contact moves, two things happen at once. The account they left now has a hole where your champion used to be, and the company they joined just acquired someone who already knows your product. New hires spend a large share of their budget in their first hundred days and are far more open to a meeting than an entrenched incumbent. So the move that quietly rots your email field is also the move that should trigger your warmest outreach of the quarter. Catching it by hand is the failure mode. By the time a rep notices the bounce, the window has closed.

In Clay, this is the Monitor for job changes signal: Actions, then Monitor for job changes. Point it at your table of contacts, and each contact's LinkedIn URL is the identifier it matches on. Turn on the optional Initial check to surface contacts whose current company already differs from your records, and set how often the signal runs. Each check costs 1 action plus 0.2 data credits, so the cost scales with how many contacts you monitor and how often.

Run the check and watch one job change fan out into three actions

Marcus Lee, VP Marketing at Northwind

Watched on LinkedIn URL · VP Marketing at Northwind

Run frequency

30

checks / contact / month

within a day

a move is caught

1 action + 0.2 credits

per check

Monitoring a 5,000-contact book scales cost with how many contacts you watch and how often. Hourly checks are Enterprise-only.

A tracked job change is worth more than the field it repairs: the same move updates the record, flags the account that lost a champion, and creates a warm lead at the contact's new company.

You can monitor three populations, and the choice matters. Watch the contacts inside your CRM to keep records current. Watch your past customer champions to protect revenue and follow them to their new company. Watch the open market to find net-new movers who fit your profile before they hit anyone else's list. Regency Supply built exactly this, monitoring thousands of contacts so that when one changes roles, the record updates itself and the rep gets pinged the same day.

5,000+

Key contacts Regency Supply keeps current by automatically tracking job changes in Clay, so reps follow the buyer to their new company.

Read the full story

For the contacts the monitor flags as moved, an AI research agent confirms the move and structures the result before you act on it. Point Claygent at the record to verify whether the person still works where your CRM says they do, and return a clean value you can route on.

Claygent prompt: confirm whether a contact still works at the stored company
Contact name: {{Full Name}}Stored company: {{Account Name}}Stored title: {{Title}}Using public web sources and the contact's current professional profile, determine whether this person still works at the stored company in the stored role. Return ONLY a JSON object, no prose:{  "still_at_company": <true | false | null>,  "current_company": "<name, or null if unconfirmed>",  "current_title": "<title, or null if unconfirmed>",  "confidence": <0-100>,  "evidence_url": "<the single best supporting URL>"}If you cannot confirm the current employer from a credible source, return null for current_company and set still_at_company to null. Do not guess and do not infer a move from an outdated cached page.

The "return null, do not guess" instruction is the part that protects your CRM. A confident wrong answer that overwrites a correct record is worse than no answer at all.

Step 4: Set the refresh cadence to balance freshness against credit cost

More frequent is not more correct; past a point, it is just more expensive.

Refreshing in Clay spends from two separate meters, and naming them keeps the cadence math honest. Actions cover the orchestration: each row enriched, exported, or synced costs one Action. Data Credits cover the provider results, fixed or variable by source, and you spend them only when a lookup returns data. A daily refresh on a 50,000-record book burns Actions on every row and Data Credits on every result, whether or not the field moved. A yearly refresh banks both meters and lets your fastest-decaying fields rot for months. The right answer is per-tier: tight cadence on the records and fields that decay fast and matter most, loose cadence on the slow and the low-priority, and no cadence at all on records you have excluded.

Set a cadence per tier and watch freshness move against Actions and Data Credits

Active-deal contacts

1,500 records · fast decay
Data freshness96%
Monthly cost
6,000 Actions
3,300 Data Credits

Target-account contacts

4,000 records · fast decay
Data freshness85%
Monthly cost
4,000 Actions
2,200 Data Credits

General contacts

40,000 records · medium decay
Data freshness85%
Monthly cost
13,200 Actions
7,260 Data Credits

Closed-lost / suppressed

8,000 records · irrelevant decay
Data freshness88%
Monthly cost
0 Actions
0 Data Credits

23,200

monthly Actions

12,760

monthly Data Credits

86%

blended freshness

Refresh cadence is a freshness-versus-cost tradeoff best solved per tier, because tightening the cadence on slow or low-priority records spends Actions and Data Credits without buying accuracy that matters.

Clay runs this with Scheduled sources, set on the source itself. Open the source, choose Run this source, then On a schedule, and pick Day, Week, or Month (Hour is Enterprise-only). Turn on the Update existing rows toggle so each re-run refreshes records already in the table instead of only adding new ones. If a tier's freshness rides on enrichment columns rather than the import, use Scheduled columns to re-run those columns on the same kind of clock. The dynamic list from Step 2 feeds it, the cadence here paces it, and the loop runs without anyone remembering to start it.

Step 5: Verify every refreshed value before it overwrites a good one

A refresh that overwrites a correct value with a worse one is not maintenance; it is damage.

This is the failure mode that kills trust faster than stale data ever could. Your monitor says a contact moved, but the source is a cached page from last year and the contact never left. The refresh fires, the correct employer gets replaced with an old one, and a rep emails the wrong company. The fix is a conditional run between the refreshed value and the record: the write executes only if the incoming value is fresher and more confident than what is already stored. A conditional run is Clay's "only run if" logic, so a value that conflicts or fails its check is skipped, never written silently. Vanta hit this exact wall before fixing it: multiple tools enriching the same point into the same field with no way to decide which result was true.

Clay has helped us simplify complex workflows, eliminate redundant tools, and make smarter decisions faster. It's become a cornerstone of our RevOps strategy.

Run the gate and watch which refreshed values overwrite and which are skipped

Marcus Lee, refreshed values arriving against the stored record

TitleDirectorvs storedSenior ManagerRecent, high confidence
CompanyTidemarkvs storedNorthwindJob-change confirmed, recent
Emailm.lee@tidemark.comvs storedmarcus@northwind.comDeliverable
Phone+1 415 555 0199vs stored+1 415 555 0188Line status: not in service
Account notes(none)vs storedRep-maintainedProtected field

On a tie, the higher source wins

Rep-verified>High-confidence enrichment>Monitor-flagged>Stale source

A conditional run only lets a refreshed value overwrite a stored one when it is both newer and trusted, so a stale source can never silently replace a value a rep relies on.

Encode that hierarchy in the conditional run and exclude manually maintained fields entirely. The point of the gate is to overwrite less, not more.

Step 6: Push verified updates back and stamp the refresh date

The write-back closes the loop, and one detail makes it a loop instead of a runaway.

Use Clay's update action to push the verified values back into HubSpot or Salesforce, keyed on the CRM record ID you carried in at Step 2, so the update lands on the existing record and never spawns a duplicate. Then, in the same write, stamp the Last Enrichment Date with the refresh date pulled from the enrichment metadata (right-click the enrichment to extract its last refresh date, and convert it to a date field if your CRM expects one). That stamp is what drops the record out of the dynamic refresh list until its next cycle. Skip it, and the same record re-qualifies immediately and gets re-enriched forever, quietly draining both Actions and Data Credits. For Salesforce, test the whole write in the Salesforce Test Env connection before it touches production; treat the first live run as a release, not an experiment, because writes cannot be undone.

This is the difference between an enrichment project and an enrichment engine. A project ends and the data slides back to stale. The engine keeps running, so coverage and accuracy climb and stay climbed. Figma built the continuous version of this: Salesforce stayed the system of record while Clay became the layer that keeps the contacts in it current, instead of letting them drift the way an audit first found them.

Common failure modes, and how to avoid them

Freshness loops break in predictable ways. Watch for these.

  • Refreshing everything on one calendar reminder.: A single cadence overspends on slow firmographics and under-refreshes fast-decaying titles and employers. Set the cadence per field and per tier, matched to the decay rate you measured.
  • Pointing the job-change monitor at the wrong field.: Monitor for job changes matches on each contact's LinkedIn URL, so a record missing that URL is invisible to the signal. Map the LinkedIn URL on import; the CRM record ID is for writing back, not for matching the move.
  • Overwriting a correct value with a stale source.: A refresh that writes a cached, lower-confidence value over a rep-trusted one trains the team to distrust the CRM. Gate every refreshed value with a conditional run, and exclude manually maintained fields from automated updates.
  • Forgetting to stamp the refresh date.: Without the Last Enrichment Date stamp, a record never leaves the dynamic list, gets re-enriched on every run, and burns Actions and Data Credits with nothing to show. Stamp the date in the same write-back that pushes the values.
  • Treating the loop as a one-time backfill.: A backfill is a snapshot of a moving target; a third of contact data decays within a year. The dynamic list, the schedule, and the conditional-run gate, running together, are the deliverable. The loop is the product, not the cleanup.

Build a CRM that keeps itself fresh

Detect decay, monitor job changes, re-enrich on a schedule, and verify before overwrite. Build the loop in Clay, free.

Frequently asked questions

How do I keep my CRM data fresh automatically instead of cleaning it manually?

Build a maintenance loop instead of a one-time cleanup. Create a Last Enrichment Date field in your CRM, then a dynamic list filtered on that date being older than your refresh window so records queue themselves as they age. Clay imports that list on a schedule, re-enriches the aged records, verifies each value with a conditional run, writes the verified ones back keyed on the CRM record ID, and stamps the refresh date so the record drops out of the queue until its next cycle. Nothing is manual after setup.

How often should I refresh CRM data to keep it accurate?

Set the cadence per tier and per field, not one global number. Title and employer decay in months and deserve a tight window for active-deal and target-account contacts; firmographics like founding year and HQ city barely move and can be enriched once. Closed-lost and do-not-contact records can be excluded entirely. Clay schedules refreshes on the source itself by Day, Week, or Month, with Hour reserved for Enterprise, so match the clock to the decay rate rather than maxing it everywhere.

Why is tracking job changes the most valuable way to keep CRM data fresh?

Because a job change rots several fields at once (employer, email, often phone and title) and is also a buying signal. The same move means your champion now sits at a new company in their first hundred days, when budgets are open and meetings are easy to get, while the account they left needs a new contact. Clay's Monitor for job changes signal matches on each contact's LinkedIn URL and costs 1 action plus 0.2 data credits per check, so you repair the record and create a warm opportunity from one event instead of discovering it through a bounced email weeks later.

How does Clay avoid overwriting good CRM data when it refreshes a record?

Every refreshed value passes through a conditional run before it writes. Clay's "only run if" logic checks the incoming value's freshness and confidence against what is already stored, so a value only overwrites when it is both newer and more trusted. Anything that conflicts or fails a deliverability or line-status check is skipped rather than written, and manually maintained fields are excluded from automated updates entirely. A trust hierarchy decides which source wins on a tie.

Does keeping CRM data fresh work with both HubSpot and Salesforce?

Yes. Clay's native integrations import a dynamic list from either CRM, run the same detect-refresh-verify-write loop, and push verified values back keyed on the CRM record ID so updates land in place without creating duplicates. For Salesforce, test the write-back in the Salesforce Test Env connection before pointing it at production, since writes cannot be undone. The loop is CRM-agnostic; only the integration and dynamic-list mechanics differ slightly between the two.