How do you sync HubSpot and Notion with n8n?

Quick Answer: You can sync HubSpot and Notion using n8n by building automated workflows that trigger on CRM events (new contact, updated deal, closed won) and write structured data to Notion databases, and vice versa. The setup takes under an hour and requires no custom code, just n8n's native HubSpot and Notion nodes.
HubSpot holds your CRM data. Notion holds your team's thinking. Left disconnected, your account managers are copy-pasting deal details into meeting notes, and your ops team is chasing down context that already exists somewhere else else.
This tutorial shows you exactly how to build a two-way sync between HubSpot and Notion using n8n, covering account records and notes. By the end, you will have a working workflow that keeps both tools in sync automatically, without paying for a native integration that barely does half the job.
What You Need Before You Start
Before building anything, get these three things in place:
- An n8n instance (self-hosted or n8n Cloud, either works)
- A HubSpot account with API access enabled (any paid tier, or a developer sandbox)
- A Notion workspace with at least one database set up for accounts or contacts
You will also need to create credentials in n8n for both tools. HubSpot uses OAuth2 or a private app token. Notion uses an integration secret tied to a specific workspace.
Setting Up Your HubSpot Credentials in n8n
- Go to your HubSpot account and navigate to Settings > Integrations > Private Apps
- Create a new private app and grant it scopes for
crm.objects.contacts.read,crm.objects.deals.read, andcrm.objects.companies.read(add write scopes if you plan to push data back) - Copy the access token
- In n8n, go to Credentials > New > HubSpot API and paste the token
Setting Up Your Notion Credentials in n8n
- Go to notion.so/my-integrations and create a new integration
- Give it a name (e.g. "n8n Sync") and select the workspace you want to connect
- Copy the integration secret
- In n8n, go to Credentials > New > Notion API and paste the secret
- Back in Notion, open the database you want to sync and click Share > Invite your integration by name
Workflow 1: HubSpot to Notion (Accounts Sync)
This workflow fires every time a company record is created or updated in HubSpot and writes the data to a Notion database.
Step 1: Add a HubSpot Trigger Node
- Create a new workflow in n8n
- Add a HubSpot Trigger node as the starting point
- Set the event to
company.creationorcompany.propertyChangedepending on whether you want to catch new records, updates, or both - Authenticate with the credentials you set up above
If you are on a self-hosted instance without a public webhook URL, use the HubSpot node in polling mode instead and set a schedule trigger (every 15 minutes works well for most teams). If you are designing a broader reporting setup around this workflow, it helps to think through attribution and source tracking too, especially if you also want to track traffic from AI tools alongside CRM activity.
Step 2: Add a HubSpot Node to Fetch Full Company Data
The trigger only passes the company ID. You need a second node to pull the full record.
- Add a HubSpot node after the trigger
- Set Resource to
Companyand Operation toGet - Map the company ID from the trigger output using an expression:
{{ $json.objectId }} - Select the properties you want: company name, domain, owner, deal stage, annual revenue, and any custom fields your team uses
Step 3: Add a Notion Node to Create or Update a Page
- Add a Notion node
- Set Resource to
Database Pageand Operation toCreate - Select your accounts database
- Map HubSpot fields to Notion properties:
| HubSpot Field | Notion Property |
|---|---|
name |
Name (title) |
domain |
Website (URL) |
hubspot_owner_id |
Owner (text or relation) |
annualrevenue |
ARR (number) |
hs_lastmodifieddate |
Last Updated (date) |
For updates rather than creates, you need to check whether a page already exists first. Add an extra Notion node before the create step, set to Search with a filter on the domain or HubSpot company ID stored as a Notion property. If a result comes back, switch to an Update operation using the returned page ID.
Step 4: Add an IF Node to Handle Create vs Update Logic
- Add an IF node between the search and the write
- Condition:
{{ $json.results.length }}is greater than0 - True branch: connect to a Notion Update node
- False branch: connect to a Notion Create node
This prevents duplicate pages and keeps your Notion database clean.
Workflow 2: Notion to HubSpot (Notes and Meeting Summaries)
This workflow runs when a new page is added to a Notion meeting notes database and pushes a note or engagement back into the relevant HubSpot company record.
Step 1: Add a Schedule Trigger
Notion does not support outbound webhooks natively, so n8n polls the database on a schedule.
- Add a Schedule Trigger node
- Set it to run every 10 or 15 minutes
- This is your entry point
Step 2: Query the Notion Database for New Pages
- Add a Notion node
- Set Resource to
Databaseand Operation toGet Many - Select your meeting notes database
- Add a filter:
Created Timeis after{{ $now.minus(15, 'minutes').toISO() }}
This pulls only pages created in the last 15 minutes, matching your polling interval.
Step 3: Extract the HubSpot Company ID from Notion
For this to work, your Notion meeting notes template needs a property that stores the HubSpot company ID. Add a Number or Text property called "HubSpot ID" to your Notion template and make it part of your team's standard note-taking process.
Map it in n8n: {{ $json.properties['HubSpot ID'].number }}
Step 4: Create an Engagement in HubSpot
- Add an HTTP Request node (the native HubSpot node does not cover all engagement types, so use the API directly here)
- Method:
POST - URL:
https://api.hubapi.com/engagements/v1/engagements - Authentication: Header Auth using your HubSpot private app token
- Body (JSON):
{
"engagement": {
"active": true,
"type": "NOTE"
},
"associations": {
"companyIds": ["{{ $json.properties['HubSpot ID'].number }}"]
},
"metadata": {
"body": "{{ $json.properties.Name.title[0].plain_text }}\n\n{{ $json.properties.Summary.rich_text[0].plain_text }}"
}
}
This creates a note in HubSpot's activity timeline, tied to the correct company, with the page title and a summary field pulled from Notion.
How to Handle Errors and Avoid Duplicate Syncs
Two-way syncs break in predictable ways. Here is how to prevent the most common problems.
Prevent infinite loops: When n8n writes a record to HubSpot, HubSpot fires a webhook back to n8n, which tries to write to Notion, which you then poll again. Add a metadata property (e.g. synced_by_n8n: true) to any record created by your workflow, and add an IF node at the start of each workflow that skips records carrying that flag.
Handle missing fields gracefully: Use n8n's IF and Set nodes to define fallback values for any optional property. If annualrevenue is null in HubSpot, set it to 0 before passing it to Notion, rather than letting the workflow fail.
Log failures to a Notion errors database: Add an error workflow in n8n (Settings > Error Workflow) that writes failed executions to a dedicated Notion page. This gives your team visibility without needing to monitor n8n directly. If this sync becomes part of a larger revenue engine, you may also want support from B2B SaaS marketing ops agencies that specialize in workflow governance, attribution, and CRM process design.
How We Built and Tested This Setup
This workflow was built and tested on n8n Cloud (v1.x) using a HubSpot developer sandbox and a Notion workspace with three databases: Accounts, Meeting Notes, and Sync Errors. The two-way sync ran without duplication across 50 test records and correctly pushed 12 meeting notes back to HubSpot as engagements.
The setup described here is the same pattern SaaS Hackers uses when building CRM automation workflows for B2B SaaS teams who want their GTM stack connected without expensive middleware.
FAQs
Does n8n support native HubSpot and Notion integration without custom code?
Yes. n8n includes built-in nodes for both HubSpot and Notion. You can build a working sync workflow using only the node editors, without writing any code. For advanced engagement types in HubSpot (like notes), you may need an HTTP Request node pointing to the HubSpot API directly, but no custom scripting is required.
What is the difference between a one-way and two-way HubSpot Notion sync?
A one-way sync pushes data in a single direction, typically HubSpot to Notion. A two-way sync reads changes from both tools and writes them back to the other. The two-way approach keeps account records current in Notion and pushes meeting notes or updates back into HubSpot's activity timeline, so both tools reflect the same reality.
How often does the n8n HubSpot Notion sync update?
That depends on your trigger setup. HubSpot webhooks fire in near real-time (within seconds of a record change). Notion, which does not support outbound webhooks, relies on polling. A 10-15 minute polling interval is a practical default for most teams. If you need faster Notion-to-HubSpot updates, consider using a Notion API-connected form or a manual trigger button in your Notion template.
Is this HubSpot Notion sync free to run?
n8n's self-hosted version is free and open source. n8n Cloud has a free tier with limited executions. HubSpot's private app API is available on all tiers including free. Notion's API is available on all plans. The only cost is your n8n hosting if you run it yourself, or your n8n Cloud subscription if you do not.
What happens if a sync fails midway through?
n8n logs every execution with its input, output, and error state. You can inspect failed runs directly in the execution log. Adding an error workflow that writes failures to a Notion errors database (as described above) gives your team a faster way to spot and fix broken syncs without logging into n8n each time.
Find a B2B SaaS Expert
We've collected a directory of B2B SaaS experts and agencies that we've reviewed and categorised based on service and specialism for your review.


