DEV Community

Zackrag
Zackrag

Posted on

Auto-Enriching Your CRM on New Contact Creation: A No-Code Webhook Playbook

Every week, someone on a sales team exports a CSV of new contacts, uploads it to their enrichment tool, waits for the batch to complete, downloads the enriched file, and re-imports it to HubSpot. By the time that loop completes, the contact has already been two days into a cold sequence — with a job title that may have already changed.

I ran this process for eight months before wiring up a reactive webhook flow. The difference wasn't marginal. Average time-to-enriched-record dropped from 2.3 days to under 40 seconds.

Why batch enrichment keeps failing you

The appeal of batch enrichment is obvious: collect a week of new contacts, enrich them all at once, pay for a single bulk job. But the model has a structural flaw — there's always a gap between when a contact enters your CRM and when your data about them is complete.

That gap matters for two reasons. First, salespeople work off incomplete records and mentally note "check this later," which they rarely do. Second, any personalization your sequences do depends on fields that are blank when they first fire.

Most enrichment guides address this by suggesting you "enrich at import." That's closer, but still doesn't handle contacts who come in via form submissions, inbound referrals, or ad platforms mid-day.

The actual fix is reactive enrichment: enrich the record the moment it's created, driven by a webhook event.

How reactive enrichment works

When a new contact is created in your CRM, a webhook fires — a small HTTP POST containing the contact's data is sent to a URL you control. Your automation platform (Zapier, Make, or n8n) receives that payload, calls your enrichment API with the contact's email (or name + company), then writes the result back to the CRM.

The entire round-trip — CRM creation to enriched record — runs in under a minute. No CSV, no manual step, no scheduled job to maintain.

The three key questions are: which enrichment APIs actually support single-record, on-demand lookups (not all do efficiently), what to do when the first API returns no match, and what this costs per enriched record compared to batch.

Which APIs actually support real-time single-record lookups

Not all enrichment tools are built for event-driven use. Some are designed around bulk batch jobs and will technically accept single-record calls, but impose aggressive rate limits that make them painful at moderate contact volumes.

I tested the main options against 500 real contacts over three months:

API Real-time single-record Rate limit Match rate (my tests) Cost per call
People Data Labs Yes 1,000 req/min ~65% $0.04–0.12
Apollo Yes (/people/match) 200 req/min ~58% Included in plan
Clearbit Yes 600 req/min ~70% $0.20–0.30
Hunter.io Yes (email enrichment only) 100 req/min ~45% Plan-based
Snov.io Yes Moderate ~50% Credits
Lusha Yes Lower ~55% Credits
Clay No — orchestration layer N/A Varies Per row

One thing comparison guides consistently get wrong: Clay is not an enrichment API. It's a waterfall orchestration tool that calls People Data Labs, Apollo, Clearbit, and others in sequence for you. It's useful, but it adds 2–8 seconds of latency per row in my runs and costs more per match than going direct. For a CRM webhook flow where you need sub-second enrichment calls, Clay is the wrong layer to hit first.

Building the HubSpot → Zapier → PDL flow

Here's the exact flow I use for HubSpot. The same pattern works with Salesforce, Pipedrive, and any CRM that supports outbound webhooks.

Step 1 — Set up the HubSpot webhook

In HubSpot, go to Settings → Integrations → Private Apps, or use the Workflows trigger. Create a workflow that fires on "Contact Created" and sends a POST to your Zapier catch hook URL.

Step 2 — Filter for email presence

Add a Filter step in Zapier: only continue if the email field is not empty. This prevents burning API credits on contacts that People Data Labs and Apollo can't match without an email address.

Step 3 — Call PDL's Person Enrich endpoint

Add a Webhooks by Zapier step: Method POST, URL https://api.peopledatalabs.com/v5/person/enrich, pass email in the body and your API key in the X-Api-Key header. The response includes job_title, job_company_name, linkedin_url, location, and ~80 other fields depending on your plan.

Step 4 — Gate on likelihood score

Before writing back to HubSpot, check the likelihood field in PDL's response. Anything below 0.7, I skip — partial matches pollute records worse than blanks. Add a Filter: only continue if likelihood >= 0.7.

Step 5 — Update HubSpot on blank fields only

Use HubSpot's "Update Contact" action, but only write fields that are currently empty. This prevents the webhook from overwriting data a rep entered manually. In Zapier you can do this with a Lookup step that checks existing field values before mapping them.

Designing a fallback chain

No single API covers 100% of contacts. PDL's match rate in my tests was 65% on typical outbound lead lists — meaning 35% of your contacts come out un-enriched if you stop there.

A fallback chain:

  1. PDL first — deepest firmographic and LinkedIn data; covers most known-name B2B contacts
  2. Apollo second — better coverage for US-based SMB contacts; use /people/match with email + first/last name
  3. Hunter.io as a floor — if both fail, at minimum verify the email is deliverable and pull any professional data Hunter has on the domain

In Zapier, implement this with a Path or a series of Filter steps gating each enrichment call on whether the previous one returned a match. In Make, the router module handles this more cleanly — I prefer Make for fallback chains because the visual branching is easier to audit when something breaks.

What to do with failed enrichments: don't delete them, and don't keep retrying on every contact creation. I write an enrichment_failed_at timestamp to a custom HubSpot property and run a nightly batch of those records through Snov.io, which handles lower-signal contacts better than PDL in my experience. That catches roughly another 12% of the initially missed records.

What this actually costs

The per-call economics look different from batch pricing:

API Per-call cost Match rate Effective cost per enriched record
People Data Labs $0.08 avg 65% ~$0.12
Apollo (Growth plan) Included credits 58% ~$0.03–0.05
Clearbit $0.25 avg 70% ~$0.36
Hunter.io ~$0.02 (email data only) 45% ~$0.04
Snov.io ~$0.03 avg 50% ~$0.06
RocketReach Credits ~55% ~$0.10

For a team adding 200 new contacts per week, a PDL-primary / Apollo-fallback chain costs roughly $12–18/week in API credits. That's less than one hour of manual enrichment time.

One cost factor most comparisons miss: rate limit overages. PDL charges overage fees once you exceed your monthly credit allotment. If you're running reactive enrichment across multiple CRMs or intake sources simultaneously, budget your credits with a 20% buffer or you'll hit surprise bills at month-end.

What I actually use

For most B2B webhook flows, I run People Data Labs as primary and Apollo as fallback. PDL's linkedin_url field alone is worth the primary position — having that on 65% of new contacts unlocks LinkedIn automation steps that need a profile URL to work.

For contacts that came in through Twitter or Facebook ads — where you have a social handle rather than a business email — Ziwa has been faster for me than hitting PDL's API directly, which tends to have lower match rates on social-first identifiers compared to email-first ones.

For complex multi-source waterfalls where I also need technographic data (current tech stack, funding round, headcount), Clay makes more sense than building the chain manually, even with the added latency. The table interface is much easier to QA than a nested Zapier sequence.

The flow that performs best for a typical outbound-focused SMB:

  1. HubSpot webhook → Zapier filter (email present)
  2. PDL enrich → likelihood gate (≥0.7) → update blank HubSpot fields
  3. On PDL miss → Apollo /people/match → update blank fields
  4. On both misses → log timestamp → nightly Snov.io batch retry

Total setup time in Zapier: about three hours, once. Maintenance overhead: near zero unless PDL changes their endpoint structure, which has happened once in 18 months and took 20 minutes to fix.

Top comments (0)