Google Sheets to SinergiaCRM, no duplicate signups
You collect registrations in a spreadsheet, then spend your afternoon copying them into a CRM. And the worst part is when someone registers twice and you only notice after the event list is already messy.
Event marketers usually feel this first. A CRM admin cleaning records feels it too. Even a small business owner running workshops ends up needing the same Sheets CRM automation to keep signups clean and usable.
This workflow watches new Google Sheets rows, checks SinergiaCRM by NIF to prevent duplicates, then registers the person and marks the row as processed. You’ll see how it works, what you need, and what to tweak.
How This Automation Works
Here’s the complete workflow you’ll be setting up:
n8n Workflow Template: Google Sheets to SinergiaCRM, no duplicate signups
flowchart LR
subgraph sg0["Google Sheets Flow"]
direction LR
n0@{ icon: "mdi:play-circle", form: "rounded", label: "Google Sheets Trigger", pos: "b", h: 48 }
n1@{ icon: "mdi:cog", form: "rounded", label: "SinergiaCRM: Create Contact", pos: "b", h: 48 }
n2@{ icon: "mdi:cog", form: "rounded", label: "SinergiaCRM: Create Relation..", pos: "b", h: 48 }
n3@{ icon: "mdi:cog", form: "rounded", label: "SinergiaCRM: Create Registra..", pos: "b", h: 48 }
n4@{ icon: "mdi:database", form: "rounded", label: "Google Sheets: Mark Procesad..", pos: "b", h: 48 }
n5@{ icon: "mdi:swap-horizontal", form: "rounded", label: "IF: to CRM == Yes", pos: "b", h: 48 }
n6@{ icon: "mdi:swap-horizontal", form: "rounded", label: "IF: Not processed == No", pos: "b", h: 48 }
n7@{ icon: "mdi:swap-horizontal", form: "rounded", label: "IF: Person exist", pos: "b", h: 48 }
n8@{ icon: "mdi:cog", form: "rounded", label: "Find person by NIF", pos: "b", h: 48 }
n9["<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/>Combinar ID del CRM"]
n10@{ icon: "mdi:cog", form: "rounded", label: "SinergiaCRM: Create Relation..", pos: "b", h: 48 }
n11@{ icon: "mdi:cog", form: "rounded", label: "SinergiaCRM: Create Registra..", pos: "b", h: 48 }
n12@{ icon: "mdi:database", form: "rounded", label: "Google Sheets: Mark Procesad..", pos: "b", h: 48 }
n13@{ icon: "mdi:swap-vertical", form: "rounded", label: "Edit Fields", pos: "b", h: 48 }
n13 --> n7
n7 --> n2
n7 --> n1
n5 --> n6
n8 --> n9
n9 --> n13
n0 --> n5
n6 --> n8
n6 --> n9
n1 --> n10
n3 --> n4
n2 --> n3
n11 --> n12
n10 --> n11
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 n5,n6,n7 decision
class n4,n12 database
classDef customIcon fill:none,stroke:none
class n9 customIcon
Why This Matters: Duplicate signups quietly ruin your CRM
Spreadsheets are great for collecting registrations, but they’re terrible at enforcing “one person, one record.” People submit twice. Someone on your team imports the same rows again “just to be safe.” Then your CRM has two contacts with the same email, one missing the NIF, and both half-registered for the event. You waste time merging records, your event counts look wrong, and follow-up emails go to the wrong segment. Honestly, it’s the kind of boring admin work that drains momentum right when you should be promoting the event.
It adds up fast. Here’s where it breaks down in real life.
- Someone has to monitor the sheet and manually push each signup into SinergiaCRM, usually in batches at the end of the day.
- Duplicate checks happen “by eyeballing,” which means a few duplicates slip through every event.
- When contacts already exist, you still need the relationship and event registration created, and that’s where manual entry mistakes happen.
- Without a clear “Processed” status back in the sheet, you can’t confidently tell what’s been imported and what hasn’t.
What You’ll Build: Google Sheets → SinergiaCRM deduped registrations
This workflow turns your Google Sheet into a reliable intake queue for SinergiaCRM. When a new registration row appears, n8n checks a couple of “should we process this?” flags so you stay in control. Then it looks up the person in SinergiaCRM using the NIF field (a much stronger identifier than a name match). If the contact already exists, the workflow skips contact creation and moves straight to creating the correct relationship and event signup. If the contact does not exist, it creates the contact first, then completes the relationship and registration. At the end, it writes back to the original Google Sheet and marks the row as processed so the same signup doesn’t get handled twice.
The workflow starts in Google Sheets and uses conditional checks to filter out rows you don’t want imported yet. SinergiaCRM handles the “contact vs. relationship vs. event signup” actions, and Google Sheets gets updated as the source of truth for what’s done.
What You’re Building
| What Gets Automated | What You’ll Achieve |
|---|---|
|
|
Expected Results
Say you run a webinar series and get about 40 signups a week in Google Sheets. Manually, it’s easy to spend maybe 2 minutes per signup to search the CRM, create or update the person, register them, and then note what you did. That’s around 80 minutes weekly, plus rework when duplicates sneak in. With this automation, you’re mostly just scanning the sheet for odd rows; the actual CRM work happens in the background, and the “Processed” marker keeps you from doing the same work twice.
Before You Start
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Google Sheets for storing registrations and processing flags.
- SinergiaCRM to create contacts, relationships, and event signups.
- OAuth credentials (set up inside Google and SinergiaCRM connectors).
Skill level: Intermediate. You won’t write code, but you will map fields, connect OAuth accounts, and confirm your sheet columns match the workflow.
Want someone to build this for you? Talk to an automation expert (free 15-minute consultation).
Step by Step
A new registration row appears in Google Sheets. The Google Sheets Trigger watches your chosen spreadsheet and worksheet for new rows coming in.
Your “ready for CRM” logic is checked. Two quick decision points look at the row’s control columns (like “To CRM” and whether it’s already marked “Processed”). This keeps the workflow from importing drafts, test rows, or anything you want to hold back.
SinergiaCRM is searched by NIF, then the right path runs. If a contact exists, the workflow merges the identifier, maps the needed fields, then creates the relationship and event signup. If there isn’t a match, it generates the contact first, then creates the relationship and signup using the “Alt” branch.
The sheet is updated so you have a paper trail. Once the CRM actions succeed, the workflow marks that row as processed in Google Sheets so it won’t be handled again.
You can easily modify the control columns to match your internal process, like changing “To CRM” into “Approved.” See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Google Sheets Trigger
Set up the workflow to listen for new rows added in your Google Sheet.
- Add and open Sheets Row Watcher.
- Set Event to
rowAdded. - Set Poll Times to
everyMinute. - Select Document as
[YOUR_ID]and Sheet asSheet1 (gid=0). - Credential Required: Connect your
googleSheetsTriggerOAuth2Apicredentials.
Step 2: Connect Google Sheets for Updates
Configure the nodes that write back to the sheet when processing is complete.
- Open Mark Sheet Processed and set Operation to
update. - Set Document to
[YOUR_ID]and Sheet toSheet1 (gid=0). - In Columns, set NIF to
{{ $('Contact Exists?').item.json.NIF }}and Processed toYes, with Matching Columns set toNIF. - Open Mark Sheet Processed 2 and set Operation to
updatewith the same document and sheet. - In Columns, set NIF to
{{ $('Generate CRM Contact').item.json.attributes.stic_identification_number_c }}and Processed toYes, with Matching Columns set toNIF. - Credential Required: Connect your
googleSheetsOAuth2Apicredentials to both update nodes.
Step 3: Set Up Filters, Lookup, and Mapping
Validate rows, check for duplicates, and normalize input data before CRM actions run.
- Configure Check CRM Flag to filter rows where To CRM equals
{{ $json['To CRM'] }}with Right Value set toYes. - Configure Verify Unprocessed to only pass rows where Processed equals
{{ $json.Processed }}with Right Value set toNo. - In Lookup Contact NIF, set Module to
Contactsand filter stic_identification_number_c with{{ $json.NIF }}. - In Merge CRM Identifier, set Mode to
combine, Join Mode toenrichInput2, and Merge By Fields toattributes.stic_identification_number_c↔NIF. - In Map Input Fields, add assignments with expressions like First name
{{ $json['First name'] }}, NIF{{ $json.NIF }}, Event ID{{ $json['Event ID'] }}, and id{{ $json.id }}.
Verify Unprocessed outputs to both Lookup Contact NIF and Merge CRM Identifier in parallel, ensuring CRM lookup and merge happen simultaneously.
Credential Required: Connect your SinergiaCRMCredentials credentials to the Sinergia CRM nodes (6 total), including Lookup Contact NIF, Create CRM Relationship, Generate CRM Contact, Create Event Signup, Create Relationship Alt, and Create Signup Alt.
Step 4: Configure CRM Actions and Branching Logic
Route existing vs. new contacts and create relationships and event signups accordingly.
- In Contact Exists?, set the condition to check that id is not empty using
{{ $json.id }}. - For existing contacts, configure Create CRM Relationship with Module
stic_Contacts_Relationshipsand Operationcreate, using{ "start_date": "{{ $json['Relation date'] }}", "relationship_type": "{{ $json['Relation type'] }}", "stic_contacts_relationships_contactscontacts_ida": "{{ $json.id }}", "assigned_user_id": "2" }. - Then configure Create Event Signup with Module
stic_Registrationsand Operationcreate, using{ "stic_registrations_contactscontacts_ida": "{{ $('Contact Exists?').item.json.id }}", "stic_registrations_stic_eventsstic_events_ida": "{{ $('Contact Exists?').item.json['Event ID'] }}", "participation_type": "attendant", "attendees": "1", "assigned_user_id": "2", "status": "confirmed", "registration_date": "{{ $('Contact Exists?').item.json['Registration date'] }}" }. - For new contacts, configure Generate CRM Contact with Module
Contactsand Operationcreate, using{ "first_name": "{{ $json['First name'] }}", "last_name": "{{ $json['Last name'] }}", "email1": "{{ $json.Email }}", "stic_identification_type_c": "nif", "stic_identification_number_c": "{{ $json.NIF }}" }. - Then set Create Relationship Alt with
{ "start_date": "{{ $('Contact Exists?').item.json['Relation date'] }}", "relationship_type": "{{ $('Contact Exists?').item.json['Relation type'] }}", "stic_contacts_relationships_contactscontacts_ida": "{{ $json.id }}", "assigned_user_id": "2" }and Create Signup Alt with{ "stic_registrations_contactscontacts_ida": "{{ $('Generate CRM Contact').item.json.id }}", "stic_registrations_stic_eventsstic_events_ida": "{{ $('Generate CRM Contact').item.json.id }}", "participation_type": "attendant", "attendees": "1", "assigned_user_id": "2", "status": "confirmed", "registration_date": "{{ $('Contact Exists?').item.json['Relation date'] }}" }.
{{ $('Generate CRM Contact').item.json.id }} for both contact and event IDs. Ensure this matches your CRM’s expected event ID, or replace the event ID value with the correct field.Step 5: Confirm Workflow Layout and Notes
Ensure the flow is correctly connected and note the informational node.
- Confirm the execution order: Sheets Row Watcher → Check CRM Flag → Verify Unprocessed → parallel Lookup Contact NIF and Merge CRM Identifier → Map Input Fields → Contact Exists? → CRM actions → sheet updates.
- Leave Flowpast Branding as a reference note; it does not affect execution.
Step 6: Test and Activate Your Workflow
Validate end-to-end behavior with a sample row, then enable the workflow for production.
- Click Execute Workflow and add a new row in the sheet with To CRM set to
Yesand Processed set toNo. - Check that the row is updated to Processed =
Yesin either Mark Sheet Processed or Mark Sheet Processed 2. - Verify that CRM records were created or updated depending on the Contact Exists? branch.
- When successful, toggle the workflow to Active for continuous monitoring.
Troubleshooting Tips
- Google Sheets credentials can expire or lose access if the spreadsheet owner changes. If things break, check the Google connection in n8n and confirm the account can still open that exact sheet.
- If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- SinergiaCRM lookups depend on NIF formatting. Extra spaces, punctuation differences, or blank NIF cells can cause “not found” results, so normalize the NIF in your sheet and make it required for processing.
Quick Answers
About 30 minutes if your Google Sheet columns are ready.
No. You will connect accounts and map 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 SinergiaCRM access costs if your plan limits API usage.
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, but keep the control logic intact. Most teams customize the Google Sheets checks (the “To CRM” and “Processed” columns) and the mapping in “Map Input Fields” so it matches their spreadsheet. You can also swap what happens after “Contact Exists?” so an existing contact only gets an event signup, not a relationship update. If you run multiple events, using a different Event ID column (or a second sheet) is a common tweak.
Usually it’s expired credentials or the community node not being available on n8n Cloud. This workflow uses SinergiaCRM community nodes, which are only compatible with self-hosted n8n, so confirm you’re running it on your own instance. After that, double-check the SinergiaCRM account permissions and make sure the NIF lookup field exists and is spelled the same way as the node expects.
Practically, dozens to hundreds of rows per day is fine for most small teams. If you self-host, there’s no execution cap (it depends on your server), and Google Sheets plus CRM API rate limits become the real bottleneck. If you expect big spikes, batch your sheet intake or run the workflow on a schedule so it processes in chunks instead of instantly per row. Also keep an eye on retries; repeated failures can create execution pileups.
For this workflow, n8n is usually a better fit because the branching logic (existing contact vs. new contact) stays readable and doesn’t get expensive as you add conditions. Self-hosting also matters here, since SinergiaCRM is implemented via community nodes and you may want unlimited runs during registration spikes. Zapier or Make can still work if you rebuild the SinergiaCRM calls with generic HTTP modules, but you’ll spend more time testing edge cases. If your process is “2 steps, no dedupe,” those tools feel faster. Talk to an automation expert if you want help choosing.
Once this is running, your spreadsheet stops being a to-do list and starts being a reliable intake pipeline. The workflow handles the repetitive CRM work so you can focus on the event itself.
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.