Airtable to HubSpot, approved leads synced clean
Copying “approved” leads from Airtable into HubSpot sounds simple. Then you do it 30 times, miss a field, create a duplicate company, and the handoff turns into a quiet mess.
This Airtable HubSpot sync hits sales ops hardest, but marketing ops and client-facing freelancers feel it too. You want one clean record in HubSpot, linked properly, with the HubSpot IDs written back so nobody has to guess.
This workflow does exactly that: it watches for “Ready to Sync” leads, creates or finds the right company, upserts the contact, associates them, and marks the Airtable row as synced (or logs the error so you can fix it fast).
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: Airtable to HubSpot, approved leads synced clean
flowchart LR
subgraph sg0["Schedule Flow"]
direction LR
n0@{ icon: "mdi:swap-vertical", form: "rounded", label: "get domain", pos: "b", h: 48 }
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/>Search company"]
n2["<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/>Create a company"]
n3["<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/merge.svg' width='40' height='40' /></div><br/>Merge"]
n4["<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/>Create or update a contact"]
n5["<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/>Sync back"]
n6["<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/>Report Failure"]
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/airtable.svg' width='40' height='40' /></div><br/>change status to Syncing..."]
n8@{ icon: "mdi:swap-horizontal", form: "rounded", label: "If company exists", pos: "b", h: 48 }
n9@{ icon: "mdi:play-circle", form: "rounded", label: "Schedule Trigger", pos: "b", h: 48 }
n10@{ icon: "mdi:swap-vertical", form: "rounded", label: "Loop Over Items", pos: "b", h: 48 }
n11@{ icon: "mdi:cog", form: "rounded", label: "🎉All Records Completed!🎉", pos: "b", h: 48 }
n12@{ icon: "mdi:cog", form: "rounded", label: "👍Done! Going for next record", pos: "b", h: 48 }
n13@{ icon: "mdi:cog", form: "rounded", label: "👎Failed! Going for next reco..", 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/>get 👍Ready to Sync"]
n3 --> n4
n3 --> n6
n5 --> n12
n5 --> n6
n0 --> n1
n6 --> n13
n1 --> n8
n10 --> n11
n10 --> n7
n2 --> n3
n2 --> n6
n9 --> n14
n8 --> n3
n8 --> n2
n14 --> n10
n4 --> n5
n4 --> n6
n7 --> n0
n12 --> n10
n13 --> n10
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 n9 trigger
class n8 decision
class n5,n6,n7,n14 database
classDef customIcon fill:none,stroke:none
class n1,n2,n3,n4,n5,n6,n7,n14 customIcon
The Problem: “Approved” Leads Still Don’t Make It Into the CRM Cleanly
Airtable is a great staging area. The trouble starts the moment “staging” becomes “source of truth,” and HubSpot becomes the place you eventually update… when you have time. Someone reviews a lead, changes the status to Ready, and then the manual work begins: copy fields, find the right company, check if the contact already exists, create associations, then tell the team it’s done. Do that under pressure and small mistakes pile up: duplicates, unlinked records, and missing IDs that break your reporting later.
It’s not one big failure. It’s the constant friction.
- Copy-pasting a handful of fields per lead turns into about 2 hours a week once volume picks up.
- Company matching by name is unreliable, so “Acme Inc” and “Acme, Inc.” quietly become two companies.
- Contacts get created without the right company association, which means ownership, lifecycle stages, and routing drift.
- No writeback of HubSpot IDs to Airtable leaves your team with brittle workarounds and lots of “which record is the real one?”
The Solution: Sync Approved Airtable Leads Into HubSpot (With Clean Companies)
This workflow treats Airtable as your lead control panel, then makes HubSpot updates automatic once a lead is approved. It runs on a schedule (every few minutes, if you want) and pulls leads from a specific Airtable view like “👍 Ready to Sync.” For each record, it marks the row as syncing, extracts the email domain, and uses that domain to find the right company in HubSpot. If the company already exists, it uses it; if not, it creates one. Then it creates or updates the contact in HubSpot, associates the contact to the company, and finally writes the HubSpot IDs back into the original Airtable row with a clean “✅ Synced” status. If something fails, it logs the failure back to Airtable so you see exactly what happened.
The workflow starts with a scheduled check of your “ready” leads. Then it processes up to 50 records per run, one-by-one, so one bad record doesn’t block the rest. At the end, Airtable becomes your audit trail: synced items show IDs, failures show notes, and nothing gets lost.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say your team approves 25 leads a week in Airtable. Manually, even a “quick” HubSpot entry is maybe 5 minutes per lead once you include company checks and association, which is about 2 hours weekly. With this workflow, approval is just changing the status to “👍 Ready to Sync,” and the scheduled run does the rest in the background. You still review exceptions, but that’s usually a couple of rows, not the whole batch.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Airtable to stage leads and control statuses
- HubSpot to create companies, contacts, associations
- HubSpot Private App Token (get it from HubSpot Settings → Integrations → Private Apps)
Skill level: Beginner. You will connect accounts, choose the right Airtable base/view, and map a few fields.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
Scheduled check for approved leads. The workflow runs on a timer (every 5 minutes is common) and pulls records from Airtable that are already in your “👍 Ready to Sync” view.
One record at a time, with a clear status. It processes up to 50 leads per run, looping through them so a single failure doesn’t block the batch. Before any CRM write happens, the Airtable row is marked as “syncing,” which helps you avoid double work if someone is watching the table live.
Company + contact logic that stays clean. n8n extracts the email domain, searches HubSpot for the matching company, and creates it if it’s missing. Then it creates or updates the contact based on email and associates that contact with the company.
Writeback you can rely on. When HubSpot returns IDs, the workflow writes them back into the same Airtable row and flips the status to “✅ Synced.” If anything fails, it logs the error to Airtable so you know what to fix without digging through execution logs.
You can easily modify which Airtable view triggers the sync to match your pipeline stages based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Scheduled Trigger
Set the schedule that starts the CRM sync cycle.
- Add the Scheduled Automation Trigger node as your workflow trigger.
- Set the schedule rule to run every
20seconds (rule interval with field set tosecondsand secondsInterval set to20). - Connect Scheduled Automation Trigger to Fetch Ready Leads.
⚠️ Common Pitfall: If the trigger fires too frequently for your API limits, increase the interval in Scheduled Automation Trigger.
Step 2: Connect Airtable
Pull ready-to-sync leads and update their status during and after processing.
- In Fetch Ready Leads, select your Airtable Base and Table, and set the View to
✅ Ready to Sync. - Set Limit to
50and Operation tosearchin Fetch Ready Leads. - Credential Required: Connect your
airtableTokenApicredentials in Fetch Ready Leads. - Configure Mark Record Syncing to Operation
updateand set id to{{ $json.id }}with Status set to🔄 Syncing.... - Credential Required: Connect your
airtableTokenApicredentials in Mark Record Syncing. - Configure Writeback to Airtable to update fields: Status
✅ Synced, Note=Successfully synced with HubSpot on {{ $now }}, HubSpot Company ID{{ $('Combine Company Paths').item.json.companyId.toString() }}, and HubSpot Contact ID{{ $('Upsert Contact Profile').item.json.vid.toString() }}. - Credential Required: Connect your
airtableTokenApicredentials in Writeback to Airtable and Log Sync Error.
⚠️ Common Pitfall: Ensure the Airtable field names match exactly (e.g., HubSpot Company ID, HubSpot Contact ID, Status) or the updates will fail.
Step 3: Set Up Processing and HubSpot Sync
Extract domains, find or create companies, and upsert contacts in HubSpot.
- In Iterate Through Records, keep batch processing enabled and connect Fetch Ready Leads → Iterate Through Records.
- Connect Iterate Through Records to Mark Record Syncing for per-record updates, and to 🎉Batch Complete Notice🎉 for end-of-batch completion.
- In Extract Email Domain, set domain to
{{ $json.fields.Email.split('@')[1] }}. - In Lookup Company Record, set Resource to
company, Operation tosearchByDomain, and Domain to=https://{{ $json.domain }}. - Credential Required: Connect your
hubspotAppTokencredentials in Lookup Company Record, Generate Company Entry, and Upsert Contact Profile. - In Check Company Presence, ensure the condition checks
{{ $json.companyId }}with the notEmpty operator. - If the company is missing, configure Generate Company Entry with Name set to
{{ $('Fetch Ready Leads').item.json['Company Name'] }}, Website URL to=http://{{ $('Extract Email Domain').item.json.domain }}, and Company Domain Name to{{ $('Extract Email Domain').item.json.domain }}. - Connect both outcomes of Check Company Presence into Combine Company Paths so that Combine Company Paths feeds Upsert Contact Profile.
- In Upsert Contact Profile, set Email to
{{ $('Fetch Ready Leads').item.json.Email }}, Job Title to{{ $('Fetch Ready Leads').item.json['Job Title'] }}, First Name to{{ $('Fetch Ready Leads').item.json.Name }}, and Associated Company ID to{{ $('Combine Company Paths').item.json.companyId }}.
Tip: The flow Extract Email Domain → Lookup Company Record → Check Company Presence ensures you only create companies when necessary.
Step 4: Configure Output and Loop Continuation
Write back success and continue the batch loop.
- Connect Upsert Contact Profile to Writeback to Airtable to mark records as synced.
- Connect Writeback to Airtable to 👍Proceed to Next Item.
- Connect 👍Proceed to Next Item back to Iterate Through Records to continue processing until completion.
- Leave 🎉Batch Complete Notice🎉 as a no-op marker for debugging and monitoring end-of-batch behavior.
Step 5: Add Error Handling
Capture failures and move on to the next record without blocking the batch.
- Ensure error paths from Combine Company Paths, Upsert Contact Profile, and Writeback to Airtable lead to Log Sync Error.
- In Log Sync Error, update Status to
❌ Errorand set Note to{{ $now }} {{ $json.toJsonString() }}. - Credential Required: Connect your
airtableTokenApicredentials in Log Sync Error. - Connect Log Sync Error to 👎Error Next Item, then back to Iterate Through Records to continue processing.
⚠️ Common Pitfall: The Log Sync Error node writes the full error payload to Airtable. Ensure the Note field can store long text.
Step 6: Test and Activate Your Workflow
Validate the sync flow end-to-end before enabling it in production.
- Click Execute Workflow and confirm Fetch Ready Leads returns records from the
✅ Ready to Syncview. - Verify a single lead flows through Mark Record Syncing, Lookup Company Record/Generate Company Entry, Upsert Contact Profile, and Writeback to Airtable.
- Check Airtable for updated Status to
✅ Syncedand populated HubSpot Company ID and HubSpot Contact ID. - If a failure occurs, confirm Log Sync Error updates the record and that 👎Error Next Item continues the batch.
- Toggle the workflow to Active to enable scheduled processing.
Common Gotchas
- HubSpot credentials can expire or need specific permissions. If things break, check your HubSpot Private App scopes and token status in HubSpot Private Apps first.
- If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Default prompts in AI nodes are generic. Add your brand voice early or you’ll be editing outputs forever.
Frequently Asked Questions
Less than 10 minutes if your Airtable base and HubSpot token are ready.
No. You will connect accounts and map a few fields in n8n.
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 HubSpot plan limits, depending on how many records you sync.
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 honestly the first customization most teams do. Add the columns to your Airtable base, then include those fields in the “Upsert Contact Profile” mapping in n8n. You can also change which Airtable view the workflow pulls from, so “Ready to Sync” matches your internal approval process. If you want notifications, connect Slack or email on the success and error paths so the right person gets pinged.
Usually it’s an expired or wrong Private App Token, or the token is missing required scopes for CRM objects. Regenerate the token (or update scopes) in HubSpot, then replace the credential in every HubSpot node used for company search/create and contact upsert. Rate limiting can also show up if you sync large batches; in that case, reduce the schedule frequency or batch size so HubSpot has breathing room.
Each scheduled run pulls up to 50 Airtable records, and you can run it as often as you like as long as your Airtable and HubSpot limits allow it.
Often, yes, because this workflow isn’t just a two-step push. It loops through batches, branches based on “company found vs not found,” and writes errors back to Airtable so your review process stays tidy. n8n also gives you a realistic path to scale: self-hosting for unlimited executions, and more control over how you handle edge cases like missing domains or partial matches. Zapier and Make can still be fine for simpler “create contact” automations, especially if you never need company association logic. If you’re on the fence, Talk to an automation expert and get a quick recommendation.
Once this is live, “approved” actually means approved. The workflow handles the repetitive CRM work, and your team gets cleaner data to build 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.