Notion to Google Contacts, labels and contacts stay tidy
Your contacts are probably scattered. A “source of truth” in Notion, a messy address book in Google Contacts, and a bunch of half-updated duplicates you don’t trust.
This Notion Google Contacts automation hits marketing ops first (because follow-ups live and die on clean data). But founders running lean and assistants keeping everything moving feel it too. You get an address book that updates itself, stays labeled, and doesn’t quietly rot.
Below is the exact workflow outcome, what it fixes, and how the sync stays organized with the right Google Contact labels.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: Notion to Google Contacts, labels and contacts stay tidy
flowchart LR
subgraph sg0["Notion New Contact Flow"]
direction LR
n0["<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/notion.dark.svg' width='40' height='40' /></div><br/>Retrieve Notion Contacts"]
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/code.svg' width='40' height='40' /></div><br/>Match Label Groups"]
n2@{ icon: "mdi:cog", form: "rounded", label: "Insert Google Contact", pos: "b", h: 48 }
n3@{ icon: "mdi:swap-vertical", form: "rounded", label: "Map Contact Attributes", pos: "b", h: 48 }
n4@{ icon: "mdi:swap-vertical", form: "rounded", label: "Iterate Contact Batch", pos: "b", h: 48 }
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/httprequest.dark.svg' width='40' height='40' /></div><br/>Retrieve Google Groups"]
n6@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Assess Group Presence", pos: "b", h: 48 }
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/notion.dark.svg' width='40' height='40' /></div><br/>Flag Notion Synced"]
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/httprequest.dark.svg' width='40' height='40' /></div><br/>Create Contact Group"]
n9@{ icon: "mdi:swap-horizontal", form: "rounded", label: "Verify Sync Status", pos: "b", h: 48 }
n10["<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/notion.dark.svg' width='40' height='40' /></div><br/>Notion New Contact Trigger"]
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/notion.dark.svg' width='40' height='40' /></div><br/>Notion Update Trigger"]
n1 --> n6
n4 --> n9
n3 --> n4
n5 --> n1
n0 --> n3
n10 --> n0
n2 --> n7
n9 --> n4
n9 --> n5
n8 --> n4
n7 --> n4
n6 --> n8
n6 --> n2
n11 --> n0
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 n10,n11 trigger
class n6,n9 decision
class n0,n7 database
class n5,n8 api
class n1 code
classDef customIcon fill:none,stroke:none
class n0,n1,n5,n7,n8,n10,n11 customIcon
The Problem: Notion and Google Contacts Drift Apart
Keeping contacts in Notion is great, until your actual day-to-day tools still rely on Google Contacts. Then you’re stuck doing the same tiny admin loop: copy a phone number, paste it, add a label, and hope you didn’t miss anything. It feels harmless in the moment. But it’s constant. Miss one update and you end up texting an old number, emailing the wrong person, or losing track of who bought what because the label never got applied.
None of these alone is the problem. Together, they are.
- New leads get added to Notion, but they never make it into your phone, which means follow-ups slip through cracks.
- Manual labeling in Google Contacts is easy to forget, so “VIP”, “Customer”, or “Purchased” groups become unreliable fast.
- Duplicates pile up when two people add the same contact from different places, and cleaning it later is a time sink.
- Teams stop trusting the system, so they keep their own personal lists, and now the mess is permanent.
The Solution: Sync Notion Contacts to Google Contacts With Labels
This workflow turns your Notion database into the driver for Google Contacts. When a contact is created or updated in Notion, n8n pulls the record, maps the fields you care about (like name and phone), then checks which Google Contact “groups” (labels) should apply based on your Notion property. If a label doesn’t exist yet, it creates it. Then it inserts the contact into Google Contacts with those labels attached. Finally, it updates the Notion record by checking an “Added to Contacts” checkbox, so the same contact won’t get re-added and duplicated.
The workflow starts from Notion triggers (new and updated contacts). It then processes each contact in a batch, verifies group labels, creates missing ones, and pushes the clean contact into Google Contacts. After that, Notion gets marked as synced, so you can see status at a glance.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say you add 10 contacts a week to Notion and you also tweak a few as deals move forward. Manually, adding each one to Google Contacts plus assigning a label is maybe 5 minutes, and fixing mistakes later is another chunk of time, so you’re easily at about 1–2 hours a week. With this workflow, you just update Notion and move on. The sync runs in the background (often within a minute), and labels show up correctly without extra clicks.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Notion as your contact database source
- Google Contacts to store contacts and labels
- Notion API access (get it from Notion’s API settings)
Skill level: Intermediate. You’ll connect OAuth credentials and confirm your Notion field names match what the workflow expects.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
Notion triggers detect changes. When a new contact is created or an existing one is edited in your Notion database, the workflow wakes up and pulls the latest record.
Contact fields get normalized. A mapping step converts your Notion properties (like name, phone, and the label-driving field) into the structure Google Contacts expects. This is also where you can extend the workflow to include email, company, or notes.
Labels are verified before inserting. The workflow fetches your existing Google Contact groups, compares them to the label coming from Notion, and creates a new group if it’s missing. Honestly, this is the part that saves the most ongoing annoyance.
Google Contacts is updated, then Notion is marked. The contact is created in Google Contacts with the correct label, and Notion is updated with an “Added to Contacts” checkbox so the workflow can prevent duplicates later.
You can easily modify the mapped fields to include email and company details based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Notion Trigger
Set up the two Notion triggers that start the workflow when new contacts are created or existing contacts are updated.
- Add and open Notion New Contact Trigger, then set Database ID to your Notion database (value:
[YOUR_ID]). - In Notion New Contact Trigger, keep the polling schedule under Poll Times as
everyWeekor change it to your desired interval. - Add and open Notion Update Trigger, set Event to
pagedUpdatedInDatabase, and set Database ID to[YOUR_ID]. - Connect both Notion New Contact Trigger and Notion Update Trigger to Retrieve Notion Contacts.
Step 2: Connect Notion and Load Contacts
Pull all records from your Notion database so the workflow can map and process contacts.
- Open Retrieve Notion Contacts and set Resource to
databasePageand Operation togetAll. - Enable Return All by setting it to
true. - Set Database ID to
[YOUR_ID]so it targets the correct Notion database.
Step 3: Set Up Processing and Batching
Map Notion fields to a consistent contact schema, then iterate through each contact in batches.
- Open Map Contact Attributes and create these assignments:
- Set firstName to
{{ $json.name }}. - Set label to
{{ $json.property_buy }}. - Set phone to
{{ $json.property_phone }}. - Set Already Added to
{{ $json.property_added_to_contacts }}. - Connect Map Contact Attributes to Iterate Contact Batch and keep Options → Reset set to
false. - Open Verify Sync Status and confirm the condition checks
{{ $('Map Contact Attributes').item.json['Already Added'].toBoolean() }}istrue.
property_buy, property_phone, property_added_to_contacts) exactly match your database schema.Step 4: Configure Google Groups, Labels, and Contact Creation
Fetch existing Google Contact Groups, match labels, create groups if missing, and insert new contacts.
- In Retrieve Google Groups, set URL to
https://people.googleapis.com/v1/contactGroupsand add query parameter pageSize set to1000. - Ensure Authentication is
predefinedCredentialTypeand Node Credential Type isgoogleContactsOAuth2Api. - Open Match Label Groups and keep the provided JavaScript to parse labels and match them against Google Contact Groups.
- In Assess Group Presence, confirm the condition checks
{{ $json.resourceName }}for array empty to decide if a group needs creation. - In Create Contact Group, set URL to
https://people.googleapis.com/v1/contactGroups, Method toPOST, and JSON Body to{ "contactGroup": { "name": "{{ $json.name }}" } }. - In Insert Google Contact, set Given Name to
{{ $('Iterate Contact Batch').item.json.firstName }}, Group to{{ $json.resourceName }}, and Phone to{{ $('Iterate Contact Batch').item.json.phone }}. - In Flag Notion Synced, set Page ID to
{{ $('Retrieve Notion Contacts').item.json.url }}and update the property Added to Contacts|checkbox totrue.
Step 5: Test and Activate Your Workflow
Validate the full path from Notion triggers to Google Contacts and Notion updates before enabling production runs.
- Use Execute Workflow and trigger a new or updated contact in Notion to fire Notion New Contact Trigger or Notion Update Trigger.
- Confirm Retrieve Notion Contacts returns records, then verify Map Contact Attributes outputs fields like
firstNameandphone. - Check that Retrieve Google Groups returns contactGroups and Match Label Groups outputs matching
resourceNamevalues. - Verify that Create Contact Group runs only when Assess Group Presence detects missing groups, and Insert Google Contact creates a contact with the correct group and phone.
- Ensure Flag Notion Synced updates the Notion record by setting Added to Contacts to
true. - Once successful, set the workflow to Active to enable continuous syncing.
Common Gotchas
- Notion OAuth credentials can expire or lack access to the right workspace. If things break, check the Notion credential in n8n and confirm the database is shared with that integration.
- If you’re using Wait-like timing (or Google’s APIs respond slowly), processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Your label field needs consistent values. If property_buy contains “Customer”, “customer”, and “Customers”, you’ll end up with three separate Google Contact groups unless you normalize it in the mapping step.
Frequently Asked Questions
About 30 minutes once your Notion database fields are ready.
No. You’ll connect accounts and confirm a few field mappings 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 your Notion and Google account usage, but there are no per-contact “AI” fees in this workflow.
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 straightforward. Add or adjust fields in the “Map Contact Attributes” (and the “Map Notion Contact Fields” mapping step) so Notion properties like Email, Company, or Notes get passed through. Common customizations include syncing email addresses, adding a company name, and rewriting labels so they match a single naming convention. Test with a couple of contacts first so you don’t create messy groups.
Most of the time it’s expired OAuth consent or the wrong Google account. Reconnect the Google Contacts credential inside n8n and confirm it has access to manage contacts and contact groups. Also check for rate limits if you’re importing a large batch, because Google can temporarily throttle requests. If it fails right after label creation, your group name may contain unexpected characters coming from Notion.
A few thousand contacts is normal if you batch them and your Google API limits aren’t being hammered.
Often, yes, because label verification and conditional logic are easier to control in n8n, and self-hosting means you’re not paying per tiny step. The practical difference shows up when you need to create missing Google Contact groups, loop through batches, and mark Notion records to prevent duplicates. You can do it in Zapier or Make, but it tends to sprawl into many paid steps and it’s harder to debug. If you only need a simple “create contact” action with one label, those tools can be fine. Talk to an automation expert if you want a quick recommendation for your exact setup.
Once this is running, your contacts stop being a chore. Notion stays your control panel, Google Contacts stays clean, and the labels finally mean what you think they mean.
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.