Google Sheets to Airtable, clean lead imports
You finally have a lead list worth importing. Then the messy part starts: duplicate companies, half-updated records, and no clean way to explain what changed (or what broke) after the run.
This lead import automation hits marketing ops teams first, but founders and agency account leads feel it too. You get verified rows from Google Sheets into Airtable, duplicates flagged instead of silently corrupting your CRM, plus a simple email report you can forward to anyone.
Below you’ll see how the workflow works, what it eliminates, and what to watch out for when you customize it for your own lead sources and fields.
How This Automation Works
See how this solves the problem:
n8n Workflow Template: Google Sheets to Airtable, clean lead imports
flowchart LR
subgraph sg0["When clicking ‘Execute workflow’ Flow"]
direction LR
n0@{ icon: "mdi:play-circle", form: "rounded", label: "When clicking ‘Execute workf..", pos: "b", h: 48 }
n1@{ icon: "mdi:cog", form: "rounded", label: "Update row(s)", pos: "b", h: 48 }
n2@{ icon: "mdi:cog", form: "rounded", label: "Get row(s)", pos: "b", h: 48 }
n3@{ icon: "mdi:cog", form: "rounded", label: "Insert row", pos: "b", h: 48 }
n4@{ icon: "mdi:cog", form: "rounded", label: "Limit", pos: "b", h: 48 }
n5@{ icon: "mdi:cog", form: "rounded", label: "Get row(s)1", pos: "b", h: 48 }
n6@{ icon: "mdi:message-outline", form: "rounded", label: "Send a message", pos: "b", h: 48 }
n7@{ icon: "mdi:cog", form: "rounded", label: "Wait1", pos: "b", h: 48 }
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/airtable.svg' width='40' height='40' /></div><br/>Create Company"]
n9@{ icon: "mdi:cog", form: "rounded", label: "Update row(s) - Creation", pos: "b", h: 48 }
n10@{ icon: "mdi:cog", form: "rounded", label: "Update row(s) - Update", 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/>Code"]
n12@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Switch", pos: "b", h: 48 }
n13@{ icon: "mdi:database", form: "rounded", label: "Get row(s) Leads", pos: "b", h: 48 }
n14["<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/airtable.svg' width='40' height='40' /></div><br/>Search Company"]
n15@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items", pos: "b", h: 48 }
n16["<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/airtable.svg' width='40' height='40' /></div><br/>Update Company"]
n17@{ icon: "mdi:database", form: "rounded", label: "Create row(s) Logs", pos: "b", h: 48 }
n11 --> n12
n4 --> n5
n7 --> n15
n12 --> n8
n12 --> n16
n12 --> n17
n2 --> n1
n3 --> n13
n5 --> n6
n1 --> n14
n8 --> n9
n14 --> n11
n16 --> n10
n15 --> n4
n15 --> n2
n13 --> n15
n17 --> n7
n10 --> n7
n9 --> n7
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 n0 trigger
class n12 decision
class n8,n13,n14,n16,n17 database
class n11 code
classDef customIcon fill:none,stroke:none
class n8,n11,n14,n16 customIcon
The Challenge: Clean lead imports without duplicates
Importing leads sounds simple until you do it more than once. The second import is where things get ugly: the same company appears with slightly different spelling, a new phone number overwrites a good one, or the CRM ends up with three “Acme Ltd” records that sales now has to untangle. And when someone asks, “How many were created vs. updated?” you’re stuck guessing or doing a manual audit. That’s time you should spend improving targeting and follow-ups, not playing database janitor.
It adds up fast. Here’s where it breaks down in real teams.
- Manual imports don’t reliably tell you what was created, updated, or skipped after the fact.
- Duplicates creep in because “company name” matching is never as consistent as you want it to be.
- When a company matches multiple records, you either overwrite the wrong one or you freeze and do nothing.
- Fixing issues later means hunting through old sheets, Slack threads, and partial Airtable history.
The Fix: Verified Google Sheets leads into Airtable, with a report
This workflow runs a controlled import into your Airtable CRM, but it does it like a careful operator, not a reckless “dump and pray” script. You start with a Google Sheet of leads where email validity has already been checked, and only rows marked as valid (“Valid Email” equals OK) are allowed through. For each lead, the workflow looks up the company in Airtable and decides what to do next: create a new company record, update the existing one, or flag a data quality issue if multiple matches show up. While it processes, it keeps an internal execution tracker inside n8n (using a Data Table) so you don’t need extra read/write clutter in Google Sheets just to understand what happened.
The workflow starts with a manual launch, pulls eligible rows from Google Sheets, then processes them in batches so it stays stable on bigger imports. At the end, Gmail sends an import report (records read, created, updated) and any “multiple match” problems are written to a Logs tab in the sheet for cleanup.
What Changes: Before vs. After
| What This Eliminates | Impact You’ll See |
|---|---|
|
|
Real-World Impact
Say you import about 2,000 verified leads from a Sheet into Airtable each week. Manually, you might spend about 1 minute per row just searching the company, deciding “create or update,” and noting problems, which is roughly 30+ hours of tedious work (and that’s before fixes). With this workflow, kickoff is basically the time it takes to press run, then wait for batch processing and the Gmail report. Most teams get their week back and only touch the handful of rows that land in the Logs tab.
Requirements
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Google Sheets for your lead source and issue logs
- Airtable to store and manage Company records
- Gmail to send the import report automatically
Skill level: Intermediate. You’ll connect accounts, confirm field mapping, and adjust one or two conditions like “Valid Email = OK.”
Need help implementing this? Talk to an automation expert (free 15-minute consultation).
The Workflow Flow
Manual run kicks things off. You launch the workflow when you’re ready to import, which is useful for campaign-based lists or weekly updates.
Only verified leads are selected. n8n reads Google Sheets (Sheet1) and filters to leads where the “Valid Email” field equals OK, so you’re not polluting Airtable with junk contacts.
Each lead is checked against Airtable. The workflow searches your Airtable Company table, then a small evaluation step decides the outcome: create a record, update the single match, or treat “multiple matches” as a data quality issue.
Tracking and reporting happen automatically. n8n’s internal Data Table updates counters for records read, created, and updated. If there’s a duplicate problem, it appends a note to a Logs tab in Google Sheets. Finally, Gmail emails the report so you can trust the run without opening Airtable at all.
You can easily modify the field mapping and matching rules to fit your own definition of “duplicate.” See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Manual Trigger
This workflow starts manually and then creates a tracking record for the run.
- Add and open Manual Launch Start to confirm it is the trigger for the workflow.
- Connect Manual Launch Start to Create Tracker Row to initialize the tracking row before processing leads.
- In Create Tracker Row, set executionId to
{{ $execution.id }}and set recordsRead, recorsCreated, and recordsUpdated to0. - Set the dataTableId in Create Tracker Row to
[YOUR_ID](EML_Import).
Tip: The tracking table is used by multiple Data Table nodes; make sure you reuse the same [YOUR_ID] throughout.
Step 2: Connect Google Sheets
Lead records are read from a Google Sheet and duplicates are logged to a separate log sheet.
- Open Retrieve Lead Rows and select the Google Sheets document ID
[YOUR_ID]and sheet nameSheet1. - Configure the filter so Valid Email equals
OK. - Credential Required: Connect your googleSheetsOAuth2Api credentials in Retrieve Lead Rows.
- Open Append Quality Log and set the destination document ID to
[YOUR_ID]and sheet name toLogs. - Map Email to
{{ $json.records[0].Email }}, Company to{{ $json.records[0].Company }}, and set Remark toData quality Issue : Presence of duplicate(s) => to be investigated. - Credential Required: Connect your googleSheetsOAuth2Api credentials in Append Quality Log.
⚠️ Common Pitfall: If the sheet names or document IDs don’t match your Google Sheet, Retrieve Lead Rows and Append Quality Log will return empty results.
Step 3: Set Up Lead Batching and Tracking Updates
This workflow batches leads, limits items for summary, and updates the tracking table through multiple Data Table nodes.
- In Iterate Lead Batches, keep default batch settings to process leads sequentially.
- Iterate Lead Batches outputs to both Limit Items and Fetch Tracker Row in parallel to process batch data and fetch the tracking row simultaneously.
- In Limit Items, set Keep to
lastItemsto retain only the latest item for summary. - Configure Fetch Tracker Row and Fetch Tracker Summary with operation set to
getand filter using{{ $('Create Tracker Row').item.json.id }}. - In Modify Tracker Row, set recordsRead to
{{ $json.recordsRead + 1 }}and filter by{{ $('Create Tracker Row').item.json.id }}. - In Increment Created Count, set recorsCreated to
{{ $('Fetch Tracker Row').item.json.recorsCreated + 1 }}. - In Increment Updated Count, set recordsUpdated to
{{ $('Fetch Tracker Row').item.json.recordsUpdated + 1 }}.
Tip: All six Data Table nodes reuse the same EML_Import table. Double-check the [YOUR_ID] values match across the tracking nodes.
Step 4: Set Up Company Lookup and Routing Logic
Leads are checked against Airtable and routed based on whether a company record exists.
- Open Lookup Company and set operation to
search. - Configure filterByFormula to
=AND({Company} = "{{ $('Iterate Lead Batches').item.json.Company }}", {Email} = "{{ $('Iterate Lead Batches').item.json.Email }}"). - Credential Required: Connect your airtableTokenApi credentials in Lookup Company.
- In Evaluate Results, keep the JavaScript logic as provided to return
resultTypevaluesnone,one, ormultiple. - In Route by Outcome, verify the three rules route on
{{ $json.resultType }}with right valuesnone,one, andmultiple. - Route by Outcome outputs to Generate Company Record, Revise Company Record, and Append Quality Log in parallel based on the branch condition.
⚠️ Common Pitfall: If Lookup Company doesn’t return a valid Airtable record, Evaluate Results will classify it as none and create a new company record.
Step 5: Configure CRM Updates and Reporting
New companies are created, existing ones are updated, and a report is emailed after processing.
- In Generate Company Record, map Airtable fields to
{{ $('Iterate Lead Batches').item.json.FieldName }}values (e.g., Company, Email, City, ZIP Code, URL Site). - Credential Required: Connect your airtableTokenApi credentials in Generate Company Record.
- In Revise Company Record, keep operation as
updateand matchingColumns set toCompanyandEmail. - Credential Required: Connect your airtableTokenApi credentials in Revise Company Record.
- In Dispatch Email Report, set sendTo to
[YOUR_EMAIL]and keep subject asREPORT EML IMPORT DE LEADS. - Keep the message template as
=Leads Import Report Number of records read: {{ $json.recordsRead }} Number of records created : {{ $json.recorsCreated }} Number of records updated : {{ $json.recordsUpdated }}. - Credential Required: Connect your gmailOAuth2 credentials in Dispatch Email Report.
- In Delay Cycle, set amount to
1to pause before the next batch loops.
Tip: Because Dispatch Email Report uses tracking counts, ensure Fetch Tracker Summary is connected from Limit Items to capture the latest totals.
Step 6: Test and Activate Your Workflow
Run a manual test to verify that records are synced and reports are sent correctly.
- Click Execute Workflow on Manual Launch Start to run a test with sample lead data.
- Confirm that Create Tracker Row writes a new tracking entry and Modify Tracker Row increments recordsRead.
- Verify Airtable updates: Generate Company Record should create new records and Revise Company Record should update matches.
- Check that Append Quality Log writes duplicates to the Logs sheet and Dispatch Email Report sends the summary email.
- When everything looks correct, switch the workflow to Active to use it in production runs.
Watch Out For
- Airtable credentials can expire or lack base access permissions. If things break, check the Airtable connection in n8n’s Credentials tab first, then confirm the base and table still exist.
- If you’re using Wait nodes or external processing, timing can drift. This workflow loops in batches and uses a delay between cycles, so increase the wait duration if later nodes sometimes run before Airtable changes are visible.
- Google Sheets logging is only helpful if the “Logs” tab structure stays consistent. If you rename tabs or columns, update the Append Quality Log mapping or the workflow will “succeed” without writing the details you need.
Common Questions
About 30 minutes if your Airtable base and Sheet columns are ready.
Yes. No coding is required, but you do need to carefully match Google Sheets columns to Airtable fields once.
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 Airtable and Google Workspace plan limits.
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.
You’ll mainly adjust the Google Sheets filter and the “company matching” logic. For example, you can change the “Valid Email = OK” condition in the lead retrieval step, then tweak the Airtable lookup to match on URL Site or Email instead of Company name. Common customizations include writing duplicates to Airtable instead of Sheets, adding an “Import Batch ID” field, and changing what counts as “multiple matches” in the evaluation logic.
Usually it’s permissions or a changed base/table. Reconnect Airtable in n8n, confirm the token still has access to the right workspace, and double-check the Company table name and field names match what the workflow expects. If it fails only on larger runs, you may be hitting Airtable rate limits, so reduce batch size or add a slightly longer wait between cycles.
Practically, it can handle thousands of rows per run; the real limit is your Airtable and Google Sheets quotas, plus how fast you want the batches to process.
Often, yes, because this workflow needs branching decisions (create vs update vs log duplicates) and a reliable execution report, not just a straight “row in, record out” sync. n8n also gives you a self-hosting option, which matters when you run imports frequently or at higher volume. Another big difference is the internal Data Table used for reporting, so you’re not forced to write counters back into external tools just to understand results. Zapier or Make can still be fine if your process is simple and you don’t care about detailed tracking. Talk to an automation expert if you’re not sure which fits.
Once this is in place, imports stop being a risky event and start being a routine. The workflow keeps Airtable clean, calls out duplicates, and gives you a report you can actually trust.
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.