Tutorial: Auto-Enrich CRM Records with Company Data
Enrich new signups, inbound leads, or imported contacts with structured company data — automatically. This tutorial shows you how to call the B2B Enrichment API when a new lead arrives and push the enriched data into your CRM.
What You'll Build
A function that takes a company domain from a new lead, enriches it via the API, and returns a clean object ready to write to HubSpot, Salesforce, or any CRM.
The Enrichment Function
JavaScript (Node.js)
async function enrichCompany(domain) {
const response = await fetch(
"https://b2b-enrichment.p.rapidapi.com/api/enrich",
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": process.env.RAPIDAPI_KEY,
},
body: JSON.stringify({
company: domain,
fields: [
"name",
"industry",
"size",
"description",
"techStack",
"socialLinks",
],
}),
}
);
if (!response.ok) {
const err = await response.json();
console.error(`Enrichment failed for ${domain}:`, err.error?.message);
return null;
}
const { data } = await response.json();
return data;
}
Python
import os
import requests
def enrich_company(domain: str) -> dict | None:
response = requests.post(
"https://b2b-enrichment.p.rapidapi.com/api/enrich",
headers={
"Content-Type": "application/json",
"X-API-Key": os.environ["RAPIDAPI_KEY"],
},
json={
"company": domain,
"fields": [
"name", "industry", "size",
"description", "techStack", "socialLinks",
],
},
timeout=30,
)
if not response.ok:
err = response.json()
print(f"Enrichment failed for {domain}: {err['error']['message']}")
return None
return response.json()["data"]
Mapping Enrichment Data to CRM Fields
The API response maps directly to standard CRM properties:
| API Field | HubSpot Property | Salesforce Field | Description |
|---|---|---|---|
name | company | Account.Name | Official company name |
industry | industry | Account.Industry | Industry classification |
size | numberofemployees | Account.NumberOfEmployees | Employee count range |
description | description | Account.Description | Company summary |
socialLinks.linkedin | linkedin_company_page | Custom field | LinkedIn URL |
Example: Webhook-Triggered Enrichment
Here's a Next.js API route that enriches a company when your form captures a new signup:
// app/api/enrich-lead/route.js
export async function POST(request) {
const { email, companyDomain } = await request.json();
const enriched = await enrichCompany(companyDomain);
if (!enriched) {
// Store the lead without enrichment — don't block signup
return Response.json({ enriched: false });
}
// Write enriched data to your CRM
// await hubspot.contacts.update(contactId, {
// company: enriched.name,
// industry: enriched.industry,
// numberofemployees: enriched.size,
// description: enriched.description,
// });
return Response.json({
enriched: true,
company: enriched.name,
industry: enriched.industry,
size: enriched.size,
});
}
Batch Enrichment for Existing Records
If you have a CSV of domains to enrich, process them sequentially with a delay to stay within rate limits:
const domains = ["stripe.com", "vercel.com", "linear.app", "notion.so"];
for (const domain of domains) {
const data = await enrichCompany(domain);
if (data) {
console.log(`${data.name}: ${data.industry}, ${data.size}`);
}
// 6-second delay = 10 requests per minute
await new Promise((resolve) => setTimeout(resolve, 6000));
}
Tips
- Extract domain from email. If you only have a lead's email address, split on
@to get the company domain. Skip free providers (gmail.com,outlook.com,yahoo.com). - Don't block signups on enrichment. Run enrichment asynchronously. If the API is slow or errors, store the lead first and enrich later.
- Request only what you need. CRM enrichment rarely needs
techStackorfounded. Fewer fields = faster responses. - Handle
nullgracefully. Not every company page exposes size or industry. Write CRM records with whatever data comes back, and skipnullfields rather than overwriting existing data.