🔓 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 to GoHighLevel, no more duplicate leads

Lisa Granqvist Partner Workflow Automation Expert

Your leads are coming in. Great. Then someone submits the form twice, your CRM creates two contacts, and now you’ve got two follow-ups going out like you don’t talk to each other.

This is the stuff that quietly wrecks your pipeline. Marketing managers see it in messy attribution. Sales reps feel it when they call the same person again. And ops ends up playing spreadsheet detective. This Sheets GHL dedupe automation keeps one clean contact record, automatically.

You’ll see exactly how the workflow catches duplicates, updates the right record in GoHighLevel, and logs everything back to Google Sheets so your reporting stays believable.

How This Automation Works

The full n8n workflow, from trigger to final output:

n8n Workflow Template: Google Sheets to GoHighLevel, no more duplicate leads

The Problem: Duplicate leads ruin follow-up and reporting

Duplicates don’t just create clutter. They create confusion at the exact moment you’re trying to move fast. A lead submits a Google Form, then submits again because they didn’t get an instant reply. Or a teammate imports a list while your form is still running. Now GoHighLevel has two contacts with the same email, different phone numbers, and two conversations tied to the wrong one. You lose time merging. You lose trust in your pipeline. And honestly, you start second-guessing every “new lead” number you show in a meeting.

The friction compounds, because the mess repeats every day.

  • Sales follow-ups get duplicated, which can make your business look sloppy or spammy.
  • Reporting becomes unreliable because one person is counted multiple times in GoHighLevel and in your Sheets exports.
  • Manual cleanup eats real time, usually 30 minutes here and there, and it always lands on the busiest person.
  • Updates get lost because the “newer” submission lives on a different contact record than the one your team is actively using.

The Solution: Sync Google Sheets leads into GoHighLevel without duplicates

This n8n workflow watches your Google Sheets form response sheet for new submissions as they come in. Each time a row is added, it pulls key contact fields (typically name, email, phone, and timestamp), then checks your master lead database sheet to see if the person already exists. If it’s a brand-new lead, the workflow creates a contact in GoHighLevel via an HTTP request and appends the lead to your master database sheet. If it’s a duplicate, it updates the existing GoHighLevel contact with the latest details and logs that duplicate event in a separate “duplicate log” sheet for tracking and analysis. No manual sorting. No guessing which record is the real one.

The workflow starts with a real-time Google Sheets trigger. Then it compares the incoming submission against your existing records, routes the lead down a “new” or “duplicate” path, and syncs the outcome back into Sheets and GoHighLevel. Your CRM stays clean, so your team can move faster without stepping on each other.

What You Get: Automation vs. Results

Example: What This Looks Like

Say your form brings in 30 leads a day, and around 5 are duplicates (repeat submitters, typos, or someone using a work email later). Manually, it’s maybe 6 minutes to search GoHighLevel, compare details, update the right record, then log what happened. That’s about 30 minutes daily, and it never feels like “real work.” With this workflow, the trigger happens instantly when the row lands in Sheets, and the check + sync runs in the background. Your time spent becomes close to zero unless you want to review the duplicate log.

What You’ll Need

  • n8n instance (try n8n Cloud free)
  • Self-hosting option if you prefer (Hostinger works well)
  • Google Sheets for form responses, master DB, duplicate log.
  • GoHighLevel to create and update CRM contacts.
  • GoHighLevel API key (get it from GoHighLevel Settings).

Skill level: Intermediate. You’ll map a few fields, set up credentials, and confirm your duplicate rules (email only, or email plus phone).

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

How It Works

A new row hits your form response sheet. The Google Sheets trigger (“Sheets Intake Trigger”) watches for new submissions so you don’t have to export anything or run a daily import.

Your workflow pulls existing leads for comparison. It retrieves records from your master lead database sheet (“Retrieve Lead Lookup”), then prepares the incoming submission fields so comparisons are consistent (email formatting, phone normalization, and so on).

Duplicates get routed, not ignored. An If check (“Database Duplicate Check”) decides if this submission matches someone you already have. If it’s new, it passes a validation filter and creates the contact in GoHighLevel (“Generate CRM Contact”), then appends the row to the master sheet (“Append Lead Record”). If it’s a duplicate, it updates the existing GoHighLevel contact (“Refresh CRM Contact”) and then writes a clean, structured entry into your duplicate log sheet (“Update Duplicate Log”).

Your team gets cleaner data everywhere. GoHighLevel stays deduped, your master sheet stays the source of truth, and the duplicate log becomes a simple way to spot trends like repeat submissions, ad fraud, or forms that confuse people.

You can easily modify the duplicate matching rules to fit your reality. Some teams match on email only, others require email plus phone, and some prefer “company + phone” for B2B. See the full implementation guide below for customization options.

Step-by-Step Implementation Guide

Step 1: Configure the Google Sheets Trigger

Set up the trigger that watches for new lead submissions in Google Sheets.

  1. Add the Sheets Intake Trigger node to your workflow.
  2. Set Document to https://docs.google.com/spreadsheets/d/[YOUR_ID]/edit.
  3. Set Sheet to https://docs.google.com/spreadsheets/d/[YOUR_ID]/edit.
  4. Confirm the polling schedule is set to Every Minute under Poll Times.
  5. Credential Required: Connect your googleSheetsTriggerOAuth2Api credentials.

Step 2: Connect Google Sheets

Configure the Sheets nodes that read existing leads and update your database.

  1. Open Retrieve Lead Lookup and set Document to [YOUR_ID] and Sheet to gid=0.
  2. Credential Required: Connect your googleSheetsOAuth2Api credentials in Retrieve Lead Lookup.
  3. Open Append Lead Record, set Operation to append, and select the same Document [YOUR_ID] and Sheet gid=0.
  4. Credential Required: Connect your googleSheetsOAuth2Api credentials in Append Lead Record.
  5. Open Update Duplicate Log, set Operation to update and Data Mode to autoMapInputData, then select Document [YOUR_ID] and Sheet gid=0.
  6. Credential Required: Connect your googleSheetsOAuth2Api credentials in Update Duplicate Log.

Step 3: Configure Duplicate Detection and Branching

Route leads based on whether they already exist in your database.

  1. In Database Duplicate Check, set the condition to compare the lead email: Left Value ={{ $('Sheets Intake Trigger').item.json['Email address'] }} and Right Value ={{ $json["Email address"] }} with Operation set to notEquals.
  2. In Validate New Lead, set the condition to Left Value ={{ $json["Email address"] }} and Right Value ={{ $('Retrieve Lead Lookup').item.json["Email address"] }} with Operation set to notEquals.
  3. Confirm execution flow: Database Duplicate Check outputs to both Validate New Lead and Refresh CRM Contact in parallel.

Step 4: Configure CRM Requests and Data Processing

Create new CRM contacts for valid leads and refresh existing contacts for duplicates.

  1. In Generate CRM Contact, set URL to https://rest.gohighlevel.com/v1/contacts/ and Send Body to On with Body Type set to json.
  2. Paste the JSON body exactly as configured, including expressions like {{ $('Sheets Intake Trigger').item.json['First Name'] }} and {{ $now }} in the JSON Body field.
  3. Credential Required: Connect your goHighLevelApi credentials in Generate CRM Contact.
  4. In Refresh CRM Contact, set URL to =https://rest.gohighlevel.com/v1/contacts?email={{ $json["Email address"] }} and set Authentication to genericCredentialType with Generic Auth Type httpHeaderAuth.
  5. Credential Required: Connect your goHighLevelApi and httpHeaderAuth credentials in Refresh CRM Contact.
  6. In Extract Contact Fields, review the code and replace "[YOUR_EMAIL]" if you want a fixed email for testing, or ensure $json.email is passed from the previous node.

⚠️ Common Pitfall: The Extract Contact Fields node uses "[YOUR_EMAIL]" as a fallback. If you don’t replace it or pass $json.email, the duplicate lookup may always fail.

Step 5: Test and Activate Your Workflow

Validate that new leads create CRM contacts and duplicates update the log correctly.

  1. Click Execute Workflow and submit a test lead in your Google Form or add a row in the sheet.
  2. Confirm that Generate CRM Contact runs for new leads and that Append Lead Record appends a row in the database sheet.
  3. Submit a duplicate lead and verify Refresh CRM ContactExtract Contact FieldsUpdate Duplicate Log updates the duplicate sheet.
  4. When the test completes successfully, switch the workflow to Active to enable live processing.
🔒

Unlock Full Step-by-Step Guide

Get the complete implementation guide + downloadable template

Common Gotchas

  • Google Sheets access can fail if the connected Google account loses permission to the spreadsheet. If it suddenly stops, check the n8n credential status and confirm the file is still shared with that account.
  • If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
  • GoHighLevel API keys get rotated, and the HTTP Request nodes will start failing fast when that happens. Regenerate the key in GoHighLevel Settings and update the credential used by “Generate CRM Contact” and “Refresh CRM Contact.”

Frequently Asked Questions

How long does it take to set up this Sheets GHL dedupe automation?

About an hour if your sheets and GoHighLevel API key are ready.

Do I need coding skills to automate Google Sheets lead deduping?

No. You’ll mostly connect accounts and map fields between Google Sheets and GoHighLevel.

Is n8n free to use for this Sheets GHL dedupe 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 GoHighLevel costs (your existing plan) since this workflow uses their API.

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 GHL dedupe workflow for matching on email + phone instead of email only?

Yes, and you should if email quality is inconsistent. Update the logic in the duplicate check (the “Database Duplicate Check” If node) so it checks both fields, and make sure “Retrieve Lead Lookup” is returning the columns you want to compare. Common customizations include normalizing phone formats, ignoring empty phone numbers, and treating “+1” variants as the same number.

Why is my GoHighLevel connection failing in this workflow?

Usually it’s an expired or replaced API key used by the HTTP Request nodes. Update the credential in n8n, then re-run a single test submission from your form response sheet. If it still fails, check that the API key has access to contacts and that you’re sending the required fields (email or phone) in the request body.

How many leads can this Sheets GHL dedupe automation handle?

Plenty for most small teams. On n8n Cloud, the limit is mainly your plan’s monthly executions; self-hosting removes that cap and shifts the limit to your server and Google Sheets API quotas. Practically, if you’re adding hundreds of rows a day, consider batching lookups and keeping your master sheet tidy so searches stay fast.

Is this Sheets GHL dedupe automation better than using Zapier or Make?

Often, yes. This workflow needs branching logic (new lead vs duplicate), a reliable lookup against an existing database, and two different API actions in GoHighLevel (create vs update), plus logging. n8n handles that kind of “real workflow” without turning every path into another paid step. Zapier or Make can still work if your volume is low and your logic is simple, but costs climb quickly once you add lookups, filters, and extra actions. If you want a second opinion on what’s best for your setup, Talk to an automation expert.

Clean data sounds boring until you see how much it changes daily execution. Set this up once, keep your GoHighLevel contacts sane, and move on to work that actually grows the pipeline.

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