Keeping HubSpot contact records rich and accurate is essential for sales and marketing teams. In this guide you’ll learn how to build an automated enrichment workflow using n8n and ExactBuyer. The workflow listens for new HubSpot contacts, calls ExactBuyer to enrich the contact and company data, updates HubSpot, and notifies your team if enrichment fails.
Why enrich HubSpot contacts?
Enriched contact profiles improve segmentation, personalization, and lead qualification. Instead of relying solely on what users manually enter, enrichment services like ExactBuyer provide company names, job titles, phone numbers, locations, social links and more. Automating this process saves time, reduces manual research, and increases conversion rates in campaigns.
What this workflow does
- Listens for newly created HubSpot contacts using the HubSpot trigger.
- Retrieves the full HubSpot contact record.
- Extracts the contact email and checks it exists.
- Sends an enrichment request to ExactBuyer using the contact email.
- Updates the HubSpot contact with returned enrichment fields (name, job title, company, phone, location).
- If enrichment fails or returns no data, triggers a Slack alert for manual review.
Prerequisites
- n8n instance (cloud or self-hosted)
- HubSpot account with developer app OAuth credentials and correct scopes
- ExactBuyer API key
- Slack webhook or Slack API credential for notifications (optional)
- Basic familiarity with n8n nodes and expressions
Key HubSpot scopes and credentials
When configuring the HubSpot trigger and HubSpot nodes you must use OAuth2. Be careful: the trigger and the HubSpot get/update nodes may require different scopes or separate OAuth credentials depending on how your HubSpot app is configured. Follow n8n’s HubSpot docs for exact required scopes.
Step-by-step workflow breakdown
1. HubSpot contact trigger
Start with the HubSpot Trigger node configured for the contact creation event. This node receives webhook payloads when a new contact is created in HubSpot. Configure the webhook in your HubSpot developer settings and connect the OAuth2 credential.
2. Retrieve HubSpot contact
Use the HubSpot node set to get operation and pass the contactId from the trigger payload. This returns the full contact properties. In the example workflow the contactId is pinned into the workflow so n8n can fetch the current contact state.
3. Extract contact keys
Use the Set node to extract fields you’ll need downstream — commonly the HubSpot internal id and the contact email. Example assignments in the Set node:
user_id = {{$json.vid}}
email = {{$json.properties.email?.value}}
4. Check email present (If node)
Before calling ExactBuyer ensure an email exists. Use an If node where the condition is that the email field is not empty. If no email is present, you can stop or send a notification for manual processing.
5. ExactBuyer enrich request (HTTP Request node)
This node calls ExactBuyer’s enrichment endpoint. Configure a generic HTTP header credential to pass your ExactBuyer API key and set the URL to the enrichment endpoint, for example: https://api.exactbuyer.com/v1/enrich. The workflow uses query parameters such as:
?email={{ $json.email }}&required=work_email,personal_email,email
Important: set the node to continue on error (onError: continueErrorOutput) if you want the workflow to handle missing results instead of failing outright.
6. Update HubSpot contact
When ExactBuyer returns data, map enrichment fields into the HubSpot node upsert or update operation. Example mappings (these use n8n expressions referencing the HTTP Request result):
gender = {{$json.result.gender}}
school = {{$json.result.education?.[0]?.school?.name}}
country = {{$json.result.location?.country}}
jobTitle = {{$json.result.employment?.job?.title}}
lastName = {{$json.result.last_name}}
firstName = {{$json.result.first_name}}
companyName = {{$json.result.employment?.name}}
companySize = {{$json.result.employment.size}}
phoneNumber = {{$json.result.phone_numbers?.[0]?.E164}}
Note: use the email from the “Extract contact keys” Set node when identifying which contact to update: {{$('Extract contact keys').item.json.email}}.
7. Handle missing enrichment and notifications
If ExactBuyer returns an error or an empty result, the workflow routes to a NoOp (or other handling node) and then to a Slack node which posts to a channel such as #alerts so your team can investigate. The Slack message can include the contact email and HubSpot id for quick review.
Error handling, rate limits and best practices
- Fail-safe: Set the HTTP Request node to continue on error so you can notify and track failed enrichment calls instead of crashing the flow.
- Rate limiting: Respect ExactBuyer API rate limits. If you expect high volume, implement batching, queuing, or rate-limit middleware.
- Retry logic: For transient errors (5xx), add a Retry or Wait node and reattempt the request a few times before notifying the team.
- Separate credentials: Use different OAuth credentials for webhook triggers and for API operations if your HubSpot app requires different scopes.
- Logging: Store the response payload and status in a database or audit log for debugging and compliance.
Privacy and compliance
When enriching personal data, ensure you are compliant with data protection regulations (GDPR, CCPA etc.). Only enrich and store data you have a lawful basis for processing. Consider:
- Recording consent where required.
- Keeping an audit log of enrichments and purpose.
- Limiting storage of sensitive personal data.
Testing and validation
- Use a staging HubSpot app and a test ExactBuyer key if available.
- Manually trigger the HubSpot webhook or create a test contact to follow the flow through n8n’s execution log.
- Inspect the HTTP Request node response and confirm field mappings before enabling updates to production contacts.
- Enable a dry-run toggle by routing updates to a log instead of HubSpot until you are confident with mappings.
Advanced tips
- Support multiple emails: If contacts can have multiple emails, implement logic to pick the best (work > personal) before calling ExactBuyer.
- Cache positive enrichments: If ExactBuyer returns stable enrichments (company, job) store them for reuse and avoid repeat API calls during short time windows.
- Trigger on updates: Consider enriching not only on creation, but also when a key property changes (e.g., email) to keep profiles current.
- Field mappings: Standardize HubSpot custom properties first so you can reliably map enrichment results into HubSpot properties.
Wrap-up
This n8n workflow creates a dependable, automated bridge between HubSpot and ExactBuyer to keep contact profiles actionable and up to date. You’ll reduce manual enrichment work and provide sales and marketing with richer data to power personalized outreach.
Ready to get started? Download the n8n workflow template, or import the JSON into your n8n instance, add your HubSpot OAuth credentials and ExactBuyer API key, and test against a staging HubSpot portal.
If you want help customizing the workflow—adding retries, batched enrichment, or GDPR controls—get in touch or subscribe for templates and tutorials.
Further reading: ExactBuyer enrichment docs · n8n HubSpot Trigger docs
Call to action: Import this template into n8n and start enriching your HubSpot contacts today — or subscribe to our newsletter for more integration recipes.
