CRM Company Data Enrichment: Automate with KVK Data
KVKBase Team

CRM Company Data Enrichment: Automate with KVK Data

Learn how to automatically enrich CRM records with up-to-date KVK data. Integration methods for HubSpot, Salesforce, and Pipedrive.

crmenrichmentautomation

CRM Company Data Enrichment: Automate with KVK Data

Your CRM is only as good as the data in it. And data decays fast: companies move, change names, get acquired, or shut down. If your team works with outdated company information, you end up with returned mail, wrong salutations, and missed opportunities.

Automatic enrichment with KVK data keeps your CRM current without manual effort.

Why company data decays

B2B data decays at a significant rate each year. The causes:

  • Companies relocate (new address, new postal code)
  • Companies change their trade name
  • Legal forms change (sole proprietorship becomes a BV)
  • Companies merge or get acquired
  • Companies are deregistered

If your CRM contains 5,000 company records, hundreds will have outdated information after a year. After two years, the problem has doubled.

The solution: periodic enrichment

Instead of importing data once and hoping it stays accurate, set up a periodic enrichment process. There are two main approaches:

1. Event-driven enrichment

Enrich company data at the moment of interaction:

  • A customer logs in: check whether the data is still current
  • An employee opens a customer record: enrich in the background
  • A new deal is created: fetch the latest details

2. Batch enrichment

Enrich all records periodically in a nightly or weekly batch:

async function enrichAllCompanies() {
  const companies = await crm.getCompaniesWithKvkNumber();

  for (const company of companies) {
    try {
      const kvkData = await kvkbase.lookup(company.kvkNumber);

      // Check for changes
      if (hasChanges(company, kvkData)) {
        await crm.updateCompany(company.id, {
          name: kvkData.tradeName,
          address: formatAddress(kvkData.address),
          isActive: kvkData.isActive,
          lastEnriched: new Date()
        });

        console.log(`Updated: ${company.kvkNumber} - ${kvkData.tradeName}`);
      }
    } catch (error) {
      console.error(`Failed: ${company.kvkNumber}`, error.message);
    }

    // Respect rate limits
    await delay(200);
  }
}

function hasChanges(existing, fresh) {
  return existing.name !== fresh.tradeName
    || existing.address !== formatAddress(fresh.address)
    || existing.isActive !== fresh.isActive;
}

HubSpot integration

HubSpot offers an extensive API for managing company records. Here is how to connect KVK data:

Field mapping

KVK fieldHubSpot fieldType
kvkNumberkvk_number (custom)String
tradeNamenameString
address.street + houseNumberaddressString
address.postalCodezipString
address.citycityString
vatNumbervat_number (custom)String
legalFormlegal_form (custom)String
isActivekvk_active (custom)Boolean

HubSpot API example

const hubspot = require('@hubspot/api-client');

async function enrichHubSpotCompany(companyId, kvkNumber) {
  const kvkData = await kvkbase.lookup(kvkNumber);

  const client = new hubspot.Client({ accessToken: process.env.HUBSPOT_TOKEN });

  await client.crm.companies.basicApi.update(companyId, {
    properties: {
      name: kvkData.tradeName,
      address: `${kvkData.address.street} ${kvkData.address.houseNumber}`,
      zip: kvkData.address.postalCode,
      city: kvkData.address.city,
      kvk_number: kvkData.kvkNumber,
      vat_number: kvkData.vatNumber || ''
    }
  });
}

Salesforce integration

Salesforce uses the Account object for company data. The integration follows a similar pattern:

Field mapping

KVK fieldSalesforce fieldObject
tradeNameNameAccount
addressBillingStreet, BillingPostalCode, BillingCityAccount
kvkNumberKVK_Number__c (custom)Account
vatNumberVAT_Number__c (custom)Account

Salesforce example (with JSForce)

const jsforce = require('jsforce');

async function enrichSalesforceAccount(accountId, kvkNumber) {
  const kvkData = await kvkbase.lookup(kvkNumber);

  const conn = new jsforce.Connection({
    loginUrl: process.env.SF_LOGIN_URL
  });
  await conn.login(process.env.SF_USERNAME, process.env.SF_PASSWORD);

  await conn.sobject('Account').update({
    Id: accountId,
    Name: kvkData.tradeName,
    BillingStreet: `${kvkData.address.street} ${kvkData.address.houseNumber}`,
    BillingPostalCode: kvkData.address.postalCode,
    BillingCity: kvkData.address.city,
    KVK_Number__c: kvkData.kvkNumber,
    VAT_Number__c: kvkData.vatNumber
  });
}

Pipedrive integration

Pipedrive uses Organizations for companies:

async function enrichPipedriveOrg(orgId, kvkNumber) {
  const kvkData = await kvkbase.lookup(kvkNumber);

  await fetch(`https://api.pipedrive.com/v1/organizations/${orgId}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      name: kvkData.tradeName,
      address: `${kvkData.address.street} ${kvkData.address.houseNumber}, ` +
               `${kvkData.address.postalCode} ${kvkData.address.city}`,
      // Custom fields for KVK and VAT
      'kvk_number_field_key': kvkData.kvkNumber,
      'vat_number_field_key': kvkData.vatNumber,
      api_token: process.env.PIPEDRIVE_TOKEN
    })
  });
}

Best practices for CRM enrichment

1. Use the KVK number as the primary key

The KVK number never changes for a company. Use it as the stable identifier to link records between your CRM and the KVK database.

2. Log all changes

Track when and what changed. This helps with troubleshooting and provides insight into how fast data decays:

async function enrichWithAuditLog(company, kvkData) {
  const changes = detectChanges(company, kvkData);

  if (changes.length > 0) {
    await crm.updateCompany(company.id, mapKvkToCrm(kvkData));
    await auditLog.write({
      companyId: company.id,
      kvkNumber: company.kvkNumber,
      changes: changes,
      timestamp: new Date()
    });
  }
}

3. Handle inactive companies

If a company has been deregistered from the KVK, you want to know. Flag these records in your CRM so your team does not try to sell to non-existent companies.

4. Respect rate limits

When batch-enriching thousands of records, build in pauses to avoid overloading the API. A delay of 200ms per request is typically sufficient.

5. Validate before you enrich

Not every record in your CRM has a KVK number, and not every stored number is valid. First filter for records that have a valid 8-digit KVK number.

Conclusion

Automatic CRM enrichment with KVK data is an investment that pays for itself quickly. Your team works with current data, invoices are accurate, and you prevent the silent erosion of your customer database.

With KVKBase as your data source and a simple script for periodic enrichment, you keep your CRM clean — without manual work.