HubSpot + Bedrijfsdata.nl: clean company records
Your HubSpot company records rot faster than anyone wants to admit. One wrong domain, a missing KvK number, or an outdated phone field, and suddenly your segmentation, routing, and reporting are all a little bit fake.
This hits marketing ops first (lists and workflows break quietly). But sales teams and small agency owners feel it too, because they’re the ones chasing bad data. With HubSpot enrichment automation, you can keep company profiles current without turning “CRM hygiene” into someone’s weekly job.
This workflow watches for company changes in HubSpot, enriches the record via Bedrijfsdata.nl, then updates the right fields back into HubSpot. You’ll see what it fixes, how matching works, and what you need to run it reliably.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: HubSpot + Bedrijfsdata.nl: clean company records
flowchart LR
subgraph sg0["Flow 1"]
direction LR
n0["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/webhook.dark.svg' width='40' height='40' /></div><br/>Hubspot - Company - Enrichme.."]
n1["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/hubspot.svg' width='40' height='40' /></div><br/>Get TEST Company Data"]
n2@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Is TEST Mode?", pos: "b", h: 48 }
n3@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Validate Incoming Data", pos: "b", h: 48 }
n4@{ icon: "mdi:cog", form: "rounded", label: "Enrich company data", pos: "b", h: 48 }
n5@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Has Known Bedrijfsdata ID", pos: "b", h: 48 }
n6@{ icon: "mdi:cog", form: "rounded", label: "Get company", pos: "b", h: 48 }
n7["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/hubspot.svg' width='40' height='40' /></div><br/>Update a company"]
n8["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/hubspot.svg' width='40' height='40' /></div><br/>Get Company Data"]
n9@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If the company profile is fo..", pos: "b", h: 48 }
n10@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If your data can be matched..", pos: "b", h: 48 }
n11["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Output only the best match"]
n12["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>Reformat for processing"]
n13@{ icon: "mdi:cog", form: "rounded", label: "Error type 1: Invalid reques..", pos: "b", h: 48 }
n14@{ icon: "mdi:cog", form: "rounded", label: "Error type 3: Bedrijfsdata.n..", pos: "b", h: 48 }
n15@{ icon: "mdi:cog", form: "rounded", label: "Error type 4 - No company fo..", pos: "b", h: 48 }
n16@{ icon: "mdi:cog", form: "rounded", label: "Error type 2 - Hubspot error", pos: "b", h: 48 }
n17@{ icon: "mdi:cog", form: "rounded", label: "Do nothing", pos: "b", h: 48 }
n6 --> n9
n6 --> n14
n2 --> n1
n2 --> n8
n8 --> n5
n8 --> n16
n7 --> n17
n7 --> n16
n4 --> n10
n4 --> n14
n1 --> n5
n1 --> n16
n3 --> n2
n3 --> n13
n12 --> n7
n5 --> n6
n5 --> n4
n11 --> n7
n10 --> n12
n10 --> n15
n9 --> n11
n9 --> n15
n0 --> n3
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n2,n3,n5,n9,n10 decision
class n0 api
class n11,n12 code
classDef customIcon fill:none,stroke:none
class n0,n1,n7,n8,n11,n12 customIcon
The Problem: HubSpot company data drifts and breaks targeting
HubSpot companies usually start “clean” for about five minutes. Then people import lists, reps create new records from email signatures, forms capture half a domain, and someone edits the company name to match a trade name. Now your workflows fire on the wrong accounts, your personalization tokens look sloppy, and you can’t trust basic filters like industry, size, or location. The worst part is the mental load. You waste time second-guessing reports and manually verifying what should have been reliable CRM data.
It adds up fast. Here’s where it breaks down in real life.
- A single missing domain can block enrichment, routing, and duplicate detection for the entire account.
- Reps end up Googling for a phone number or LinkedIn page, then pasting it into the wrong record.
- Segmentation becomes guesswork because employee count and industry are inconsistent across records.
- You clean data once, and two weeks later imports and edits undo the work.
The Solution: Real-time Bedrijfsdata.nl enrichment inside HubSpot
This n8n workflow listens for a HubSpot company event (commonly a property change on the domain, but you can also use create events). When it receives a webhook, it validates the payload so random calls do not create bad updates. Then it pulls the company record from HubSpot and decides how to match it to Bedrijfsdata.nl. If a Bedrijfsdata prospect/company ID already exists on the record, it uses that first. If not, it enriches in real time using the available details (like domain) and runs a simple “can we match?” check before it writes anything back.
Once a profile is found, the workflow normalizes the returned attributes (so your fields get consistent formatting), then updates HubSpot with verified Dutch business data like KvK, LinkedIn URL, phone, and company size. If something fails, the workflow routes to dedicated error paths, which means you can troubleshoot without guessing.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say your team creates or updates about 30 company records in a week, and each one needs four quick checks (KvK, LinkedIn, phone, and company size). Manually, that’s maybe 6 minutes per check once you include tab switching and copy-paste, so roughly 12 hours of busywork a week. With this workflow, updating a company triggers the webhook instantly, the Bedrijfsdata lookup runs in the background, and HubSpot gets updated automatically. You’ll still spot-check the occasional edge case, but the default becomes “already filled in.”
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- HubSpot to receive webhooks and update companies
- Bedrijfsdata.nl for verified Dutch company enrichment
- Bedrijfsdata.nl API credentials (get them from your Bedrijfsdata developer account)
Skill level: Intermediate. You will connect credentials, map a few HubSpot properties, and test a webhook event end-to-end.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
A HubSpot webhook fires. A company event (often a property change on domain) hits the n8n webhook node, so enrichment only runs when something actually changes.
The workflow validates and fetches the company. It checks the incoming payload (portalId, objectId, event type) and then pulls the latest company record from HubSpot, which avoids updating based on stale data.
Bedrijfsdata matching runs with a smart fallback. If the record already has a Bedrijfsdata prospect ID, the workflow retrieves that exact profile. If not, it calls the enrichment step and confirms a match is possible before proceeding. When multiple candidates exist, a small code step selects the top match.
HubSpot updates happen after normalization. The workflow formats the returned attributes for your internal field structure, then updates the HubSpot company. If the API fails or no match exists, the run ends in an explicit error branch, not a half-updated record.
You can easily modify which HubSpot properties trigger enrichment and which Bedrijfsdata fields are written back based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Webhook Trigger
Set up the webhook entry point so HubSpot can send enrichment events into the workflow.
- Add the HubSpot Enrichment Webhook node as your trigger.
- Set the HTTP Method to
POST. - Set the Path to
b5e3e64f-f57a-4d08-8631-9bc61416193dand copy the generated test URL for HubSpot.
Step 2: Connect HubSpot Data Access
These nodes read and update HubSpot company records during the enrichment flow.
- Open Fetch Sample Company Record and keep Resource set to
companyand Operation toget. - Set Company ID to the test company (already set to
7611838964in sample mode). - Open Fetch HubSpot Company and set Company ID to
{{ $json.body[0].objectId }}for live events. - Open Modify HubSpot Company and keep Resource to
companyand Operation toupdate. - In Modify HubSpot Company, set Company ID to
{{ $('HubSpot Enrichment Webhook').first().json.body[0].objectId !== 123 ? $('HubSpot Enrichment Webhook').first().json.body[0].objectId : $('Fetch Sample Company Record').first().json.companyId }}. - Credential Required: Connect your hubspotOAuth2Api credentials in Fetch Sample Company Record, Fetch HubSpot Company, and Modify HubSpot Company.
Step 3: Validate Incoming Payload and Sample Mode Routing
Confirm the webhook payload is valid and decide whether to use the sample record or the live HubSpot record.
- In Verify Incoming Payload, configure three conditions:
{{ !!$json.body[0].objectId }}equals true,{{ $json.body[0].portalId }}equals139601726, and{{ $json.body[0].subscriptionType }}equalscompany.propertyChange. - In Check Sample Mode, set the condition to
{{ $json.body[0].objectId }}equals123to route to Fetch Sample Company Record. - Ensure the false output of Check Sample Mode connects to Fetch HubSpot Company.
123 before going live.Step 4: Enrich and Normalize Company Data
Use Bedrijfsdata to enrich company details and normalize the response for updating HubSpot.
- In Check Existing Prospect ID, set the condition to
{{ !!$json.properties.prospectpro_id.value && $json.properties.prospectpro_id.value !== '' }}to decide between retrieval and enrichment. - In Retrieve Prospect Company, set ID to
{{ $json.properties.prospectpro_id.value }}and enable Details. - In Enrich Company Profile, set URL to
{{ $json.properties.domain.value }}, City to{{ $json.properties.city.value}}, and Name to{{ $json.properties.name.value }}, with Details enabled. - In Confirm Profile Found, set the condition to
{{ $json.total }}greater than0before proceeding to Select Top Match. - In Confirm Match Possible, set the condition to
{{ $json.found }}greater than0before proceeding to Normalize For Update. - Credential Required: Connect your bedrijfsdataApi credentials in Retrieve Prospect Company and Enrich Company Profile.
Step 5: Map and Update HubSpot Company Fields
Transform the selected company data and write it back to HubSpot.
- In Select Top Match, keep the JavaScript that returns the first match from
input.companies?.[0]. - In Normalize For Update, keep the JavaScript that returns
input.companyto standardize fields. - In Modify HubSpot Company, map update properties: prospectpro_id to
{{ $json.id }}, kvk to{{ $json.coc }}, and linkedin_link to{{ Array.isArray($json.linkedin_link) ?$json.linkedin_link[0] : $json.linkedin_link }}. - Confirm the success output from Modify HubSpot Company connects to End Without Action.
Step 6: Add Error Handling Paths
Route failures to clear end points for easier debugging.
- Connect the failure output of Verify Incoming Payload to Error: Invalid HubSpot Call.
- Connect failure outputs of Fetch HubSpot Company, Modify HubSpot Company, and Fetch Sample Company Record to Error: HubSpot Failure.
- Connect failure outputs of Enrich Company Profile and Retrieve Prospect Company to Error: Bedrijfsdata API.
- Connect the false outputs of Confirm Profile Found and Confirm Match Possible to Error: No Company Found.
Step 7: Test and Activate Your Workflow
Run a full test to ensure the webhook, enrichment, and update sequence works end-to-end.
- Click Execute Workflow and trigger the HubSpot Enrichment Webhook with a sample payload where
objectIdis123to test sample mode. - Confirm the execution follows Verify Incoming Payload → Check Sample Mode → Fetch Sample Company Record → Check Existing Prospect ID and continues through enrichment to Modify HubSpot Company.
- Verify in HubSpot that prospectpro_id, kvk, and linkedin_link are updated on the target company.
- When satisfied, toggle the workflow to Active and update HubSpot to use the production webhook URL.
Common Gotchas
- HubSpot private app permissions matter a lot. If updates suddenly fail, check the private app scopes for Companies and review webhook delivery logs in HubSpot first.
- If Bedrijfsdata.nl returns no match, it’s often because the domain is missing or malformed (extra spaces, http prefixes, or a personal email domain). Clean the domain before enrichment or route those cases to manual review.
- The code-based “top match” and normalization steps are powerful, but they can overwrite fields you consider source-of-truth. Decide up front which properties should never be replaced (like owner notes or custom lifecycle fields) and exclude them from the update mapping.
Frequently Asked Questions
About 45 minutes if your HubSpot and Bedrijfsdata accounts are ready.
No. You’ll mostly connect credentials and map fields in the HubSpot update step.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need Bedrijfsdata.nl credits (their trial includes about 500 credits).
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
Yes, and it’s a common tweak. You can change the HubSpot webhook subscription from company.propertyChange on domain to a create event, or trigger on different properties (like VAT, website, or a custom “enrich now” checkbox). Most teams also customize which Bedrijfsdata attributes write back, by editing the field mapping in the “Modify HubSpot Company” update step.
Usually it’s expired OAuth credentials or missing company scopes on your HubSpot private app. Reconnect the HubSpot credential in n8n, then re-check the app permissions and webhook delivery logs in HubSpot. If failures happen only on busy days, rate limiting can also show up, so throttling executions or batching updates can help.
It can handle thousands of company updates per month, as long as your n8n plan and Bedrijfsdata credits cover the volume.
Often, yes. This workflow uses branching logic (sample mode checks, payload verification, error routes, and match fallback) that’s clumsy and expensive in many no-code tools once you go past a simple two-step Zap. n8n also gives you the option to self-host, which is handy when you have lots of HubSpot property changes and don’t want to pay per tiny execution. Another practical difference is control: you can normalize fields with code so HubSpot stays consistent, not “whatever the last lookup returned.” Zapier or Make can still be fine for very small setups, but this workflow is built for real CRM hygiene. If you want help deciding, Talk to an automation expert.
Clean company data changes everything downstream, from targeting to reporting to how confident your team feels in the CRM. Set this up once, and let Bedrijfsdata.nl keep HubSpot honest.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.