🔓 Unlock all 10,000+ workflows & prompts free Join Newsletter →
✅ Full access unlocked — explore all 10,000 AI workflow and prompt templates Browse Templates →
Home n8n Workflow
January 22, 2026

Google Sheets + HubSpot: enriched leads, no cleanup

Lisa Granqvist Partner Workflow Automation Expert

Your lead lists look fine until you try to use them. Missing emails, half-filled names, random company fields, and duplicates that somehow multiply after every import.

Demand gen managers feel it when “launch week” turns into spreadsheet triage. Sales ops gets stuck cleaning the CRM instead of improving it. And if you run a small agency, you’re the one doing both. This Sheets HubSpot enrichment automation turns raw rows into validated HubSpot contacts you can actually follow up with.

You’ll see how the workflow reads a Google Sheet, enriches leads in Surfe (in safe batches), filters out bad data, and only then updates HubSpot. Clean in. Clean out.

How This Automation Works

The full n8n workflow, from trigger to final output:

n8n Workflow Template: Google Sheets + HubSpot: enriched leads, no cleanup

The Problem: Lead enrichment turns into CRM cleanup

Manually enriching leads is one of those tasks that looks small, then eats your afternoon. You export a list from an event tool or partner spreadsheet, paste it into a new sheet, hunt for missing company domains, and still end up with contacts that bounce or can’t be called. Worse, you import anyway because the team needs “something,” and now HubSpot has contacts with no email, no phone, and just enough info to create duplicates later. It’s draining. It also makes follow-ups slower because reps don’t trust the data.

The friction compounds. Here’s where it breaks down.

  • Someone has to enrich records one-by-one (or juggle multiple tools) before anything is ready for outreach.
  • You can’t easily tell which rows are “good enough,” so questionable leads slip into HubSpot and clog lists.
  • Bulk enrichment often hits API limits, which means retries, splitting files, and a lot of babysitting.
  • Every manual import increases the chance of duplicates and inconsistent property mapping.

The Solution: Upload a sheet, enrich in Surfe, sync only validated contacts

This workflow flips the process around. Instead of pushing raw leads into HubSpot and fixing them later, you drop a Google Spreadsheet into a specific Google Drive folder and let n8n do the heavy lifting. n8n reads the rows, groups them into batches of 500 (so Surfe’s bulk API stays happy), and sends the batch for enrichment. While Surfe works, the workflow checks job status on a short delay loop until results are ready. Then it parses the enriched data, keeps only contacts that have both an email and a phone number, and upserts those into HubSpot. Finally, it sends you a Gmail confirmation so you know the run completed.

The workflow starts with a Google Drive file watcher, so you don’t have to click anything in n8n. It enriches leads through Surfe’s Bulk Enrichment API, then filters and upserts into HubSpot. Your CRM gets the “ready to use” subset only.

What You Get: Automation vs. Results

Example: What This Looks Like

Say you upload a sheet of 1,000 leads from an event. Manually, enrichment is easily 2 minutes per lead once you factor in lookups, copy-paste, and formatting, which is about 30 hours of work before you even import. With this workflow, you drop the spreadsheet into the Drive folder (2 minutes), n8n processes two batches of 500, and Surfe runs in the background while the workflow polls for completion. You typically come back to a HubSpot list that’s already populated with validated contacts, plus an email telling you it’s done.

What You’ll Need

  • n8n instance (try n8n Cloud free)
  • Self-hosting option if you prefer (Hostinger works well)
  • Google Drive to trigger on new spreadsheet uploads
  • Google Sheets to read rows from the uploaded sheet
  • Surfe API key (get it from your Surfe dashboard)
  • HubSpot to create or update contacts in your CRM
  • Gmail to send a completion notification email

Skill level: Intermediate. You’ll connect a few credentials and confirm your sheet columns match the expected format.

Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).

How It Works

A new spreadsheet lands in the right Drive folder. The Google Drive Trigger (“Drive File Watcher”) detects the file automatically, so the workflow can run without anyone opening n8n.

Rows are pulled and prepared for bulk enrichment. n8n reads the sheet, then splits the leads into batches of 500 and builds the JSON payload Surfe expects (including name plus company name or company domain, and LinkedIn URL if you have it).

Surfe enrichment runs, then n8n waits and checks status. A bulk request kicks off the Surfe job. The workflow pauses for about 30 seconds, checks the job status, and repeats until enrichment is done.

Validated contacts get synced to HubSpot. n8n parses the returned people results, filters out entries missing either email or phone, and upserts the rest into HubSpot. A Gmail message confirms completion.

You can easily modify the validation rule (email only vs. email + phone) to match how your team qualifies leads. See the full implementation guide below for customization options.

Step-by-Step Implementation Guide

Step 1: Configure the Google Drive Trigger

This workflow starts when a new Google Sheet is created in a specific Drive folder.

  1. Add and open Drive File Watcher.
  2. Set Event to fileCreated.
  3. Set Trigger On to specificFolder.
  4. Set Folder To Watch to the folder ID used in the node’s folderToWatch field (replace [YOUR_ID]).
  5. Credential Required: Connect your Google Drive credentials.
Make sure the folder contains Google Sheets files only, since Drive File Watcher is configured with a spreadsheet file type filter.

Step 2: Connect Google Sheets

The newly created Sheet ID is used to read rows for enrichment.

  1. Open Retrieve Sheet Rows.
  2. Set Document ID to {{ $json.id }}.
  3. Set Sheet Name to Sheet1 (value gid=0).
  4. Credential Required: Connect your Google Sheets credentials.
⚠️ Common Pitfall: If the new file is not a Google Sheet, Retrieve Sheet Rows will fail because the Document ID expression expects a spreadsheet file.

Step 3: Set Up Batch Processing and Enrichment Requests

Rows are processed in batches, then sent to Surfe for bulk enrichment with a retry loop.

  1. Open Batch Records 500 and set Batch Size to 500.
  2. Connect Batch Records 500 to Build Enrichment Payload and Send Completion Email — these run in parallel.
  3. In Build Enrichment Payload, review the JavaScript that maps item.json.linkedin_url into the request payload.
  4. In Bulk Enrich Request, set URL to https://api.surfe.com/v2/people/enrich, Method to POST, and JSON Body to {{ $json }}.
  5. In Bulk Enrich Request, set the Authorization header to Bearer [CONFIGURE_YOUR_TOKEN] with your Surfe token.
  6. In Enrichment Status Check, set URL to https://api.surfe.com/v2/people/enrich/{{ $json.enrichmentID }}.
  7. In Check Enrichment Done, ensure the condition checks {{ $json.status }} equals COMPLETED.
  8. Connect the “false” path of Check Enrichment Done to Delay 30 Seconds, and keep Amount at 30 seconds to poll again.
⚠️ Common Pitfall: If the Surfe token is missing or invalid, both Bulk Enrich Request and Enrichment Status Check will fail. Update the Authorization header in both nodes.

Step 4: Configure Parsing, Filtering, and HubSpot Updates

Once enrichment is completed, results are parsed, filtered for usable contacts, and upserted into HubSpot.

  1. In Parse People Results, verify the JavaScript maps the first email and mobile phone into email and phone.
  2. Open Filter Contact Details and keep the two conditions that ensure {{ $json.phone }} and {{ $json.email }} are not empty.
  3. Open Upsert HubSpot Contact and set Authentication to appToken.
  4. Set Email to {{ $json.email }} and map additional fields like First Name to {{ $json.firstName }} and Company Name to {{ $json.companyName }}.
  5. Credential Required: Connect your HubSpot credentials.
The loop continues because Upsert HubSpot Contact connects back to Batch Records 500, allowing all rows to be processed in batches.

Step 5: Configure the Completion Email

When the batch flow completes, a notification email is sent.

  1. Open Send Completion Email.
  2. Set Send To to your email address (replace [YOUR_EMAIL]).
  3. Set Subject to Your batch csv enrichment is done..
  4. Set Message to Your batch csv enrichment is done..
  5. Credential Required: Connect your Gmail credentials.

Step 6: Test and Activate Your Workflow

Verify that the trigger, enrichment loop, and HubSpot updates work end-to-end before enabling production mode.

  1. Click Execute Workflow and upload a new Google Sheet into the watched folder to trigger Drive File Watcher.
  2. Confirm Retrieve Sheet Rows reads the data and Batch Records 500 starts processing items.
  3. Verify Bulk Enrich Request returns an enrichmentID and Enrichment Status Check eventually returns COMPLETED.
  4. Check that Upsert HubSpot Contact creates or updates contacts with enriched data.
  5. Confirm the email from Send Completion Email is delivered after processing finishes.
  6. When successful, toggle the workflow to Active to run in production.
🔒

Unlock Full Step-by-Step Guide

Get the complete implementation guide + downloadable template

Common Gotchas

  • Google Drive/Sheets OAuth permissions are picky. If the trigger fires but rows don’t load, check the credential in n8n and confirm the Google account has access to the target folder and file.
  • If you’re using Wait nodes or external enrichment, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
  • HubSpot upserts can fail quietly when your private app token lacks scopes. Double-check the Private App permissions for contacts read/write, then re-test the “Upsert HubSpot Contact” node.

Frequently Asked Questions

How long does it take to set up this Sheets HubSpot enrichment automation?

About an hour if your Google, Surfe, and HubSpot accounts are ready.

Do I need coding skills to automate Sheets HubSpot enrichment?

No. You’ll connect credentials and paste in your Surfe API key. The workflow’s code nodes are already set up for payload building and parsing.

Is n8n free to use for this Sheets HubSpot enrichment workflow?

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 to factor in Surfe API costs based on your enrichment volume.

Where can I host n8n to run this automation?

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.

Can I customize this Sheets HubSpot enrichment workflow for email-only validation instead of email + phone?

Yes, but be intentional. You can change the “Filter Contact Details” logic to keep leads that only have email, then pass them to “Upsert HubSpot Contact.” Common customizations include requiring a company domain, mapping extra Surfe fields into HubSpot properties, and writing enriched results back to a “processed” Google Sheet for auditing.

Why is my HubSpot connection failing in this workflow?

Usually it’s the private app token scopes. Regenerate the token (or update scopes) so it includes contacts read/write, then update the credential used by the “Upsert HubSpot Contact” node. Also check that your HubSpot account hasn’t restricted the app, and watch for rate limiting if you’re pushing very large lists.

How many leads can this Sheets HubSpot enrichment automation handle?

A lot. The workflow batches 500 records at a time, so lists of several thousand are normal as long as your Surfe plan and HubSpot API limits support it. On n8n Cloud Starter you’re capped by monthly executions, while self-hosting has no execution cap (it mostly depends on your server). Practically, the waiting/polling step is what sets the pace, not the parsing.

Is this Sheets HubSpot enrichment automation better than using Zapier or Make?

Often, yes. This workflow needs batching, looping, and polling a long-running job, and frankly that’s where no-code “quick zaps” start to get annoying or expensive. n8n handles branching logic cleanly, and you can self-host for unlimited runs if you process big lists. Zapier or Make can still be fine for tiny imports, like a 20-row sheet once a month. Talk to an automation expert if you want a quick recommendation based on your volume and tooling.

Once this is running, your team stops treating HubSpot like a junk drawer. Upload the file, get enriched contacts, move on.

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.

Lisa Granqvist

Workflow Automation Expert

Expert in workflow automation and no-code tools.

×

Use template

Get instant access to this n8n workflow Json file

💬
Get a free quote today!
Get a free quote today!

Tell us what you need and we'll get back to you within one working day.

Get a free quote today!
Get a free quote today!

Tell us what you need and we'll get back to you within one working day.

Launch login modal Launch register modal