AutomationFlowsEmail & Gmail › Sync CRM Contacts with Mailchimp and Pipedrive

Sync CRM Contacts with Mailchimp and Pipedrive

Byvinci-king-01 @vinci-king-01 on n8n.io

This workflow keeps your contact records perfectly aligned between your CRM (e.g. HubSpot / Salesforce / Pipedrive) and Mailchimp. Whenever a contact is created or updated in one system, the automation propagates the change to the other platform, ensuring every email address,…

Webhook trigger★★★★☆ complexity19 nodesHTTP RequestPipedriveMailchimp
Email & Gmail Trigger: Webhook Nodes: 19 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #13225 — we link there as the canonical source.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "JZ8C3IFRtHrntshw",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "CRM Contact Sync with Mailchimp and Pipedrive",
  "tags": [],
  "nodes": [
    {
      "id": "ad3a6351-b389-4c84-9821-c630039d67de",
      "name": "Incoming Contact Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        288,
        400
      ],
      "parameters": {
        "path": "crm-contact-sync",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 1
    },
    {
      "id": "5a7326b9-121d-4e12-99a0-63f67fb4e35e",
      "name": "Split Contacts",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        480,
        400
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "2920cb9e-f9f0-45aa-9682-ff14f89fec80",
      "name": "Fetch Contact Details (Source CRM)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        688,
        400
      ],
      "parameters": {
        "url": "https://api.sourcecrm.com/contacts/{{$json.contactId}}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "httpHeaderAuth"
      },
      "typeVersion": 4
    },
    {
      "id": "857756fa-ed62-4ed2-8f36-a063e3fd8a85",
      "name": "Normalize Contact Data",
      "type": "n8n-nodes-base.code",
      "position": [
        912,
        400
      ],
      "parameters": {
        "jsCode": "// normalise source CRM contact fields\nconst src = $input.item.json;\nreturn [{\n  json: {\n    contactId: src.id || src.vid || src.contactId || '',\n    email: src.email || src.properties?.email?.value || '',\n    firstName: src.firstName || src.properties?.firstname?.value || '',\n    lastName: src.lastName || src.properties?.lastname?.value || '',\n    phone: src.phone || src.properties?.phone?.value || '',\n    company: src.company || src.properties?.company?.value || '',\n    updatedAt: src.updatedAt || src.properties?.lastmodifieddate || new Date().toISOString()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "d43aef50-dade-4eae-ac30-6df77bdd50b0",
      "name": "Search Person by Email",
      "type": "n8n-nodes-base.pipedrive",
      "position": [
        1088,
        288
      ],
      "parameters": {
        "term": "={{ $json.email }}",
        "resource": "person",
        "operation": "search",
        "returnAll": true,
        "additionalFields": {}
      },
      "typeVersion": 1
    },
    {
      "id": "3e8aa3da-b08e-4f14-a620-f8e2c47d5158",
      "name": "Combine Contact & Search",
      "type": "n8n-nodes-base.merge",
      "position": [
        1088,
        496
      ],
      "parameters": {
        "mode": "mergeByIndex",
        "options": {}
      },
      "typeVersion": 2
    },
    {
      "id": "76039f69-fd0c-46b8-8ca8-447b2c263733",
      "name": "Determine Existence & Prepare Data",
      "type": "n8n-nodes-base.code",
      "position": [
        1376,
        400
      ],
      "parameters": {
        "jsCode": "const item = $input.item.json;\nlet exists = false;\nlet personId = null;\nif (item.data && item.data.items && item.data.items.length > 0) {\n  exists = true;\n  personId = item.data.items[0].item.id;\n}\nreturn [{\n  json: {\n    ...item,\n    exists,\n    personId\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "88ae0120-b273-4211-b27f-c1eb64a7b236",
      "name": "Is Person Existing?",
      "type": "n8n-nodes-base.if",
      "position": [
        1600,
        400
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json.exists }}"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "8412367f-3c78-42ea-83a5-9582da1cdc0e",
      "name": "Create Person",
      "type": "n8n-nodes-base.pipedrive",
      "position": [
        1920,
        528
      ],
      "parameters": {
        "name": "={{ $json.firstName + ' ' + $json.lastName }}",
        "resource": "person",
        "additionalFields": {}
      },
      "typeVersion": 1
    },
    {
      "id": "6547b18d-f675-4890-ba35-6b3e257a63ba",
      "name": "Prepare New Notification",
      "type": "n8n-nodes-base.code",
      "position": [
        2112,
        528
      ],
      "parameters": {
        "jsCode": "const d = $input.item.json;\nreturn [{ json: { ...d, notificationType: 'new' } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "1953300c-92df-4603-9aeb-e6947b7c3a93",
      "name": "Update Person",
      "type": "n8n-nodes-base.pipedrive",
      "position": [
        1920,
        336
      ],
      "parameters": {
        "personId": "={{ $json.personId }}",
        "resource": "person",
        "operation": "update",
        "updateFields": {}
      },
      "typeVersion": 1
    },
    {
      "id": "100ebfaa-0123-45e2-b32e-4a2f30eb1158",
      "name": "Prepare Updated Notification",
      "type": "n8n-nodes-base.code",
      "position": [
        2448,
        320
      ],
      "parameters": {
        "jsCode": "const d = $input.item.json;\nreturn [{ json: { ...d, notificationType: 'updated' } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "e579c91d-09eb-429d-a0c0-a0e7ec9cc12f",
      "name": "Merge Notifications",
      "type": "n8n-nodes-base.merge",
      "position": [
        2640,
        496
      ],
      "parameters": {
        "mode": "mergeByIndex",
        "options": {}
      },
      "typeVersion": 2
    },
    {
      "id": "8ba16c91-af56-48e6-9296-f0c6acb69022",
      "name": "Build Mailchimp Payload",
      "type": "n8n-nodes-base.code",
      "position": [
        2896,
        432
      ],
      "parameters": {
        "jsCode": "const { email, firstName, lastName, notificationType } = $input.item.json;\nreturn [{\n  json: {\n    email,\n    firstName,\n    lastName,\n    tag: notificationType === 'new' ? 'New' : 'Updated'\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "5640ca3e-be77-47b6-a2b4-484db733a681",
      "name": "Send Sync Notification",
      "type": "n8n-nodes-base.mailchimp",
      "position": [
        3104,
        368
      ],
      "parameters": {
        "options": {},
        "mergeFieldsUi": {
          "mergeFieldsValues": [
            {},
            {}
          ]
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b6afc1b9-0ee5-41f6-9b61-e615f9e587d7",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -624,
        32
      ],
      "parameters": {
        "width": 550,
        "height": 834,
        "content": "## How it works\nThis workflow keeps contact records aligned across your CRM stack whenever the source CRM fires a webhook. Each inbound contact ID is expanded into full profile data via the source-CRM REST API, normalised into a common schema, and compared against Pipedrive. If the person already exists we update only the changed fields; otherwise we create a new person. Every successful sync is mirrored to Mailchimp so marketing lists stay fresh, while any workflow error auto-routes to a separate Mailchimp list for the operations team.\n\n## Setup steps\n1. Create a webhook in your source CRM pointing to the URL generated by the **Incoming Contact Webhook** node.  \n2. Add your Source-CRM credentials to the **Fetch Contact Details** HTTP node.  \n3. Configure Pipedrive credentials for all Pipedrive nodes.  \n4. Enter your Mailchimp API credentials & List IDs in the Mailchimp nodes.  \n5. Adjust field mappings in the two *Prepare Notification* code nodes if you need extra data.  \n6. Activate the workflow and run a test contact from your CRM to verify end-to-end syncing."
      },
      "typeVersion": 1
    },
    {
      "id": "3c6bdf3a-bab1-4cf5-8bb4-ee3d8b129bda",
      "name": "Trigger & Source",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        272,
        48
      ],
      "parameters": {
        "color": 7,
        "width": 610,
        "height": 734,
        "content": "## Trigger & Source\n\nThis section ingests webhook events from any modern CRM (HubSpot, Salesforce, etc.) that can push contact notifications. The **Incoming Contact Webhook** node exposes a POST endpoint that receives one or many contact IDs. Because webhooks often batch multiple changes, we immediately fan-out the payload using **Split Contacts**, then enrich each ID with the complete contact profile through an authenticated **HTTP Request** call to your source CRM. The **Normalize Contact Data** code node flattens vendor-specific field names into a shared format (email, firstName, lastName, phone, company, updatedAt). Keeping a single canonical shape at this early stage makes the downstream logic vendor-agnostic and easy to extend to additional CRMs later."
      },
      "typeVersion": 1
    },
    {
      "id": "0fab0022-c26b-49ef-813e-a8256946e42b",
      "name": "Pipedrive Sync",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        896,
        64
      ],
      "parameters": {
        "color": 7,
        "width": 1394,
        "height": 718,
        "content": "## Pipedrive Sync\n\nNodes in this block handle the heavy lifting of matching incoming contacts against Pipedrive and writing changes. After normalisation we perform a **Search Person by Email** operation which returns zero or more potential matches. A quick **Merge** combines the search response with the source data so we can evaluate both in one place. The **Determine Existence & Prepare Data** code node extracts personId (when found) and flags whether we are in *create* or *update* mode. The **IF** node then routes the execution accordingly: new contacts go to **Create Person**, existing ones to **Update Person**. Field mappings are kept lean but you can enrich them with any custom fields Pipedrive supports."
      },
      "typeVersion": 1
    },
    {
      "id": "4481f4eb-66fa-47f6-ae78-9fdbf57ee80e",
      "name": "Notification & Error Handling",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2304,
        64
      ],
      "parameters": {
        "color": 7,
        "width": 1026,
        "height": 622,
        "content": "## Mailchimp Notification & Error Handling\n\nOnce Pipedrive confirms a successful create or update, the workflow prepares a concise payload for Mailchimp. Both success branches funnel into a **Merge Notifications** node, then a small code snippet decorates the payload with a contextual tag (*New* or *Updated*) before passing it to **Send Sync Notification**. This Mailchimp call performs an upsert operation so your marketing audience is always in lock-step with the CRM. An isolated **Error Trigger** path captures any failure in the entire workflow and fires a secondary Mailchimp call that sends an alert to your operations list. This keeps the alerting mechanism consistent and avoids scattering credentials across multiple services."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "403277de-94ba-4d15-a7b0-7d8799bcde63",
  "connections": {
    "Create Person": {
      "main": [
        [
          {
            "node": "Prepare New Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Person": {
      "main": [
        [
          {
            "node": "Prepare Updated Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Contacts": {
      "main": [
        [
          {
            "node": "Fetch Contact Details (Source CRM)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Person Existing?": {
      "main": [
        [
          {
            "node": "Update Person",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Create Person",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Notifications": {
      "main": [
        [
          {
            "node": "Build Mailchimp Payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Contact Data": {
      "main": [
        [
          {
            "node": "Search Person by Email",
            "type": "main",
            "index": 0
          },
          {
            "node": "Combine Contact & Search",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search Person by Email": {
      "main": [
        [
          {
            "node": "Combine Contact & Search",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Send Sync Notification": {
      "main": [
        []
      ]
    },
    "Build Mailchimp Payload": {
      "main": [
        [
          {
            "node": "Send Sync Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine Contact & Search": {
      "main": [
        [
          {
            "node": "Determine Existence & Prepare Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Incoming Contact Webhook": {
      "main": [
        [
          {
            "node": "Split Contacts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare New Notification": {
      "main": [
        [
          {
            "node": "Merge Notifications",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Prepare Updated Notification": {
      "main": [
        [
          {
            "node": "Merge Notifications",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Determine Existence & Prepare Data": {
      "main": [
        [
          {
            "node": "Is Person Existing?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Contact Details (Source CRM)": {
      "main": [
        [
          {
            "node": "Normalize Contact Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow keeps your contact records perfectly aligned between your CRM (e.g. HubSpot / Salesforce / Pipedrive) and Mailchimp. Whenever a contact is created or updated in one system, the automation propagates the change to the other platform, ensuring every email address,…

Source: https://n8n.io/workflows/13225/ — original creator credit. Request a take-down →

More Email & Gmail workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Email & Gmail

Automate WhatsApp communication for recruitment agencies with an interactive, structured customer experience. This workflow handles pricing inquiries, request submissions, tracking, complaints, and hu

HTTP Request, Google Sheets, Gmail +1
Email & Gmail

This template turns Podium's conversation inbox into a full sales CRM with a custom funnel, AI message classification, automated drip follow-ups, daily admin reports, and a live Kanban dashboard. Six

HTTP Request, Google Sheets, Gmail
Email & Gmail

Suspicious_login_detection. Uses postgres, httpRequest, noOp, html. Webhook trigger; 43 nodes.

Postgres, HTTP Request, Gmail +1
Email & Gmail

This n8n workflow is designed for security monitoring and incident response when suspicious login events are detected. It can be initiated either manually from within the n8n UI for testing or automat

Postgres, HTTP Request, Gmail +1
Email & Gmail

This workflow automates a document approval process using Supabase and Gmail. Teams that need structured multi-level document approvals. Companies managing policies, contracts, or proposals. Medical d

Supabase, Crypto, Gmail +3