CRM data enrichment for developers
Your CRM is full of sparse records. Name and email — maybe. Job title — sometimes. Company size, industry, phone number — rarely. And the data you do have is decaying at 22-30% per year as people change jobs, companies get acquired, and phone numbers go stale.
The standard solution is to buy another SaaS tool: Clay, ZoomInfo, Apollo, or one of the dozens of CRM enrichment platforms that charge per seat, per month, and require yet another dashboard to manage.
If you're a developer, there's a better way.
The Problem with CRM Enrichment Platforms
They're Expensive
ZoomInfo starts at ~$15,000/year. Clay starts at $149/month. Apollo charges per seat. For a startup or small team, these prices are absurd for what amounts to a data lookup service.
They Add Another Dashboard
You already have a CRM. Now you need a separate enrichment platform with its own login, its own UI, its own learning curve. Some of these platforms are genuinely complex — Clay has an entire spreadsheet-like interface with formulas and waterfall logic.
They're Designed for Sales Ops, Not Developers
The enrichment happens through a GUI: upload a CSV, click "enrich," wait for results, download. Or set up a Zapier/Make integration that runs on triggers. Either way, it's point-and-click automation — not code.
They Lock You In
Most CRM enrichment platforms want to own your workflow. They encourage you to build sequences, campaigns, and automations inside their platform instead of your CRM. Now you have two systems to maintain.
The Developer Approach
Instead of adding another platform, use a CLI tool to enrich CRM data programmatically:
$ salesforce query "SELECT Email FROM Contact WHERE Industry = null" > unenriched.csv
$ cat unenriched.csv | while read email; do
enrich email "$email" --json
done > enriched.jsonl
$ cat enriched.jsonl | your-crm-update-script
No new dashboard. No per-seat pricing. Just a script that runs when you need it.
Practical Workflows
1. Enrich on Import
When new contacts are added to your CRM (from a form, CSV import, or API), enrich them immediately:
#!/bin/bash
# enrich-new-contacts.sh
# Run after every batch import
NEW_CONTACTS="$1"
while IFS=',' read -r name email; do
enriched=$(enrich email "$email" --json 2>/dev/null)
if [ $? -eq 0 ]; then
title=$(echo "$enriched" | jq -r '.person.title // empty')
company=$(echo "$enriched" | jq -r '.company.name // empty')
industry=$(echo "$enriched" | jq -r '.company.industry // empty')
headcount=$(echo "$enriched" | jq -r '.company.headcount // empty')
echo "$name,$email,$title,$company,$industry,$headcount"
else
echo "$name,$email,,,,"
fi
done < "$NEW_CONTACTS" > enriched_import.csv
echo "Enriched $(wc -l < enriched_import.csv) contacts"
2. Nightly Enrichment of Sparse Records
Set up a cron job that finds CRM records missing key fields and enriches them:
#!/bin/bash
# nightly-enrich.sh
# Cron: 0 2 * * * /path/to/nightly-enrich.sh
# Query CRM for contacts missing job title
psql -c "SELECT email FROM contacts WHERE title IS NULL AND email NOT LIKE '%gmail%' LIMIT 100" \
-t -A | while read email; do
result=$(enrich email "$email" --json 2>/dev/null)
if [ $? -eq 0 ]; then
title=$(echo "$result" | jq -r '.person.title // empty')
company=$(echo "$result" | jq -r '.company.name // empty')
if [ -n "$title" ]; then
psql -c "UPDATE contacts SET title='$title', company='$company' WHERE email='$email'"
fi
fi
done
3. Re-Enrich Stale Records
Contacts older than 6 months probably have decayed data. Re-enrich them:
#!/bin/bash
# re-enrich-stale.sh
# Find contacts enriched more than 6 months ago
psql -c "SELECT email FROM contacts WHERE enriched_at < NOW() - INTERVAL '6 months' LIMIT 200" \
-t -A | while read email; do
enrich email "$email" --json 2>/dev/null
done > refreshed.jsonl
echo "Re-enriched $(wc -l < refreshed.jsonl) stale records"
With enrichcli, cached results are free. If a person's data hasn't changed, the cache returns the existing data at no credit cost. You only pay for genuinely new lookups.
4. Lead Scoring Script
Enrich leads and automatically score them based on company size and seniority:
#!/bin/bash
# score-leads.sh
while read email; do
data=$(enrich email "$email" --json 2>/dev/null)
[ $? -ne 0 ] && continue
name=$(echo "$data" | jq -r '.person.name')
title=$(echo "$data" | jq -r '.person.title')
headcount=$(echo "$data" | jq -r '.company.headcount')
score=0
# Score by seniority
case "$title" in
*CEO*|*CTO*|*VP*|*Director*) score=$((score + 30)) ;;
*Manager*|*Lead*|*Head*) score=$((score + 20)) ;;
*) score=$((score + 10)) ;;
esac
# Score by company size
case "$headcount" in
*1000*|*5000*|*10000*) score=$((score + 30)) ;;
*100*|*200*|*500*) score=$((score + 20)) ;;
*) score=$((score + 10)) ;;
esac
echo "$email,$name,$title,$headcount,$score"
done < leads.txt | sort -t',' -k5 -rn > scored_leads.csv
CRM-Specific Integration Tips
Salesforce
Use the Salesforce CLI (sf) alongside enrichcli:
$ sf data query -q "SELECT Id, Email FROM Contact WHERE Title = null" --json \
| jq -r '.result.records[] | [.Id, .Email] | @csv' > to_enrich.csv
$ while IFS=',' read -r id email; do
data=$(enrich email "$email" --json 2>/dev/null)
[ $? -ne 0 ] && continue
title=$(echo "$data" | jq -r '.person.title // empty')
echo "$id,$title"
done < to_enrich.csv > updates.csv
$ sf data bulk upsert -s Contact -f updates.csv -i Id
HubSpot
Use HubSpot's API alongside enrichcli:
$ curl -s "https://api.hubapi.com/crm/v3/objects/contacts?properties=email,jobtitle&limit=100" \
-H "Authorization: Bearer $HUBSPOT_TOKEN" \
| jq -r '.results[] | select(.properties.jobtitle == null) | .properties.email' \
| while read email; do
enrich email "$email" --json
done > hubspot_enriched.jsonl
Any CRM with a REST API
The pattern is always the same:
- Query your CRM for records missing data
- Enrich those records with enrichcli
- Update your CRM with the enriched data
The specific API calls change, but the enrichment step is always the same: enrich email "$email" --json.
Cost Comparison
Running CRM enrichment with enrichcli vs. dedicated platforms:
| Scenario | enrichcli Cost | Clay Cost | Apollo Cost |
|---|---|---|---|
| 500 contacts/month | $29/month (Pro) | $149/month | $49/user/month |
| 2,000 contacts/month | $79/month (Growth) | $149/month | $79/user/month |
| 5,000 contacts/month | $79/month (Growth) | $349/month | $119/user/month |
| 10,000 contacts/month | $199/month (Team) | $800/month | $119/user/month x seats |
No per-seat pricing. No annual contracts. Cached re-enrichments are free.
When to Use a Platform Instead
Be honest: CLI-based enrichment isn't for everyone.
Use a platform (Clay, Apollo, etc.) if:
- Your team is non-technical and needs a GUI
- You need waterfall enrichment across 10+ data providers
- You want built-in email sequences alongside enrichment
- You need native Salesforce/HubSpot sync without writing code
Use enrichcli if:
- You're comfortable writing shell scripts
- You want enrichment as part of a data pipeline
- You want simple, credit-based pricing
- You're building custom workflows that platforms can't support
- You're a developer who prefers code over dashboards
Getting Started
$ brew install enrichcli/tap/enrichcli
$ enrich email someone-from-your-crm@company.com --json
$ vim enrich-crm.sh
50 free enrichments per day. Start by enriching your 50 most important sparse contacts and see what you get back.
start enriching data from the command line.
get started free50 free enrichments per day. no credit card required.