{
  "id": "nvpImrURIU8lwmmG",
  "name": "HubSpot to Klaviyo Sync: Auto-Enrich Contacts and Trigger Email Sequences",
  "tags": [],
  "nodes": [
    {
      "id": "fae2888a-b2c5-44a8-8658-2e36a15230ac",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "color": 0,
        "width": 480,
        "height": 1108,
        "content": "## HubSpot to Klaviyo Sync Bridge using n8n\n\nIf you run HubSpot for CRM and Klaviyo for email, you know the pain -- new contacts sit in HubSpot without ever reaching Klaviyo, sequences never fire on time, and your lists go stale. This workflow fixes that permanently.\n\n### How it works\n\n1. HubSpot fires a webhook the moment a new contact is created in your account.\n2. The workflow fetches the full contact record from HubSpot including lifecycle stage, company, deal value, and any custom properties.\n3. A Code node maps the HubSpot contact data to the correct Klaviyo list and tag based on lifecycle stage -- Lead, MQL, SQL, or Customer.\n4. The contact is created or updated in Klaviyo via API with all mapped properties and the correct list assignment.\n5. The appropriate Klaviyo flow is triggered for that contact based on their lifecycle stage -- for example, a welcome sequence for new leads or an onboarding sequence for new customers.\n6. A confirmation is sent to a Slack channel with the contact name, stage, and which Klaviyo list they were added to.\n7. Every sync is logged to Google Sheets with a timestamp, contact details, stage, and Klaviyo list name.\n\n### Setup steps\n\n- [ ] **HubSpot webhook** -- In HubSpot go to Settings, Integrations, Private Apps or use the Webhooks API. Create a webhook that fires on Contact Created and paste the URL from the Receive HubSpot Contact node.\n- [ ] **HubSpot API key** -- Create a Private App in HubSpot with read access to Contacts. Copy the access token and add it to the Configure Mapping and Settings node.\n- [ ] **Klaviyo API key** -- In Klaviyo go to Account, Settings, API Keys and create a Private API Key with full access. Add it to the Configure Mapping and Settings node.\n- [ ] **Klaviyo list IDs** -- In Klaviyo go to Lists and Segments. Copy the List ID for each list you want to sync to (Lead, MQL, SQL, Customer) and add them to the Settings node.\n- [ ] **Slack** -- Connect your Slack account in Notify Sync Complete and set your channel. Right-click and Disable if unused.\n- [ ] **Google Sheets** -- Create a sheet called Klaviyo Sync Log with columns: Timestamp, Name, Email, Company, HubSpot Stage, Klaviyo List, Status. Connect your Google account in Log Sync to Sheets.\n- [ ] Activate the workflow and create a test contact in HubSpot to verify the sync works end to end.\n\n### Customization\n\nAdd more lifecycle stage mappings in the Map to Klaviyo List node to match your exact HubSpot pipeline. Add a branch to also update existing Klaviyo profiles when a HubSpot contact updates their lifecycle stage. Extend with a Clearbit or Apollo HTTP Request to enrich company data before syncing."
      },
      "typeVersion": 1
    },
    {
      "id": "9659a586-7b3a-403b-a3e0-5ad0f92bde6f",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 440,
        "height": 440,
        "content": "## Receive and fetch HubSpot contact\n\nHubSpot fires a webhook on Contact Created. A second HTTP Request fetches the full contact record including all properties, lifecycle stage, and company data from the HubSpot API."
      },
      "typeVersion": 1
    },
    {
      "id": "9dcec29c-3b27-4a22-bfe2-be76f1fbf53e",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1040,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 428,
        "height": 448,
        "content": "## Map contact to Klaviyo list\n\nA Code node reads the HubSpot lifecycle stage and maps it to the correct Klaviyo list ID and tag. Edit the Settings node to add your actual Klaviyo list IDs -- no other node needs changing."
      },
      "typeVersion": 1
    },
    {
      "id": "c4050a43-5e9b-48ce-a5e9-657165593f8b",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1520,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 448,
        "height": 444,
        "content": "## Sync to Klaviyo\n\nTwo HTTP Requests handle the Klaviyo side: the first creates or updates the profile with all HubSpot properties, the second adds the profile to the correct list. Both use your Klaviyo Private API key."
      },
      "typeVersion": 1
    },
    {
      "id": "b1ccb5f8-fb5d-48d1-a000-81d70718e28a",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2064,
        -32
      ],
      "parameters": {
        "color": 7,
        "width": 344,
        "height": 584,
        "content": "## Alert and log\n\nSends a Slack notification confirming which Klaviyo list the contact was added to, then logs the full sync record to Google Sheets. Slack is optional -- right-click and Disable if unused."
      },
      "typeVersion": 1
    },
    {
      "id": "586bb3a3-d12c-46a2-b039-1ce952aa792d",
      "name": "Receive HubSpot Contact",
      "type": "n8n-nodes-base.webhook",
      "position": [
        592,
        272
      ],
      "parameters": {
        "path": "hubspot-new-contact",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "lastNode"
      },
      "typeVersion": 2
    },
    {
      "id": "4ef295f6-b095-45bb-b94b-869be38cb527",
      "name": "Configure Mapping and Settings",
      "type": "n8n-nodes-base.code",
      "position": [
        832,
        272
      ],
      "parameters": {
        "jsCode": "// ================================================\n//  EDIT THIS NODE -- all your settings live here\n// ================================================\n\nconst HUBSPOT_ACCESS_TOKEN = 'YOUR_HUBSPOT_ACCESS_TOKEN';\nconst KLAVIYO_API_KEY      = 'YOUR_KLAVIYO_API_KEY';\n\n// Map HubSpot lifecycle stages to Klaviyo list IDs\n// Find list IDs in Klaviyo under Lists and Segments\nconst LIST_MAP = {\n  'lead':       'YOUR_KLAVIYO_LEADS_LIST_ID',\n  'marketingqualifiedlead': 'YOUR_KLAVIYO_MQL_LIST_ID',\n  'salesqualifiedlead':     'YOUR_KLAVIYO_SQL_LIST_ID',\n  'customer':   'YOUR_KLAVIYO_CUSTOMERS_LIST_ID',\n  'subscriber': 'YOUR_KLAVIYO_LEADS_LIST_ID',\n  'default':    'YOUR_KLAVIYO_LEADS_LIST_ID'\n};\n\n// ================================================\n//  DO NOT EDIT BELOW THIS LINE\n// ================================================\n\nconst body = $input.first().json.body || $input.first().json;\nconst contactId = body.objectId || body.vid || body.id || body.contactId || '';\n\nreturn [{\n  json: {\n    hubspot_token: HUBSPOT_ACCESS_TOKEN,\n    klaviyo_key:   KLAVIYO_API_KEY,\n    list_map:      LIST_MAP,\n    contact_id:    String(contactId),\n    timestamp:     new Date().toISOString()\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "d7df539b-2a45-41ee-8550-9122f940b719",
      "name": "Fetch Full HubSpot Contact",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1072,
        272
      ],
      "parameters": {
        "url": "={{ 'https://api.hubapi.com/crm/v3/objects/contacts/' + $json.contact_id + '?properties=email,firstname,lastname,company,phone,lifecyclestage,hs_lead_status,jobtitle,industry,annualrevenue,createdate' }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "={{ 'Bearer ' + $json.hubspot_token }}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "cd18bffb-cce6-4168-a8eb-477a0db98095",
      "name": "Map to Klaviyo List",
      "type": "n8n-nodes-base.code",
      "position": [
        1328,
        272
      ],
      "parameters": {
        "jsCode": "const cfg       = $('Configure Mapping and Settings').first().json;\nconst hsContact = $input.first().json;\nconst props     = hsContact.properties || {};\n\nconst stage     = (props.lifecyclestage || 'default').toLowerCase().replace(/[^a-z]/g,'');\nconst listId    = cfg.list_map[stage] || cfg.list_map['default'];\nconst listName  = stage.charAt(0).toUpperCase() + stage.slice(1);\n\nreturn [{ json: {\n  klaviyo_key:   cfg.klaviyo_key,\n  klaviyo_list:  listId,\n  list_name:     listName,\n  hubspot_id:    hsContact.id,\n  email:         props.email        || '',\n  first_name:    props.firstname    || '',\n  last_name:     props.lastname     || '',\n  company:       props.company      || '',\n  phone:         props.phone        || '',\n  job_title:     props.jobtitle     || '',\n  industry:      props.industry     || '',\n  annual_revenue:props.annualrevenue|| '',\n  lifecycle_stage: listName,\n  timestamp:     cfg.timestamp\n}}];"
      },
      "typeVersion": 2
    },
    {
      "id": "1a531dad-a8f0-4cd6-a037-446ef36b4392",
      "name": "Create Klaviyo Profile",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1584,
        272
      ],
      "parameters": {
        "url": "https://a.klaviyo.com/api/profiles/",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {}
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "={{ 'Klaviyo-API-Key ' + $json.klaviyo_key }}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "revision",
              "value": "2024-02-15"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "0a5a7463-0a7b-433d-8041-2fd31cef9aa9",
      "name": "Add to Klaviyo List",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1824,
        272
      ],
      "parameters": {
        "url": "={{ 'https://a.klaviyo.com/api/lists/' + $('Map to Klaviyo List').item.json.klaviyo_list + '/relationships/profiles/' }}",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {}
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "={{ 'Klaviyo-API-Key ' + $('Map to Klaviyo List').item.json.klaviyo_key }}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "revision",
              "value": "2024-02-15"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "d6d86c1c-177a-43e8-9479-40a82e2d9605",
      "name": "Notify Sync Complete",
      "type": "n8n-nodes-base.slack",
      "position": [
        2112,
        160
      ],
      "parameters": {
        "text": "HubSpot contact synced to Klaviyo\n\nName: {{ $('Map to Klaviyo List').item.json.first_name }} {{ $('Map to Klaviyo List').item.json.last_name }}\nEmail: {{ $('Map to Klaviyo List').item.json.email }}\nCompany: {{ $('Map to Klaviyo List').item.json.company }}\nHubSpot stage: {{ $('Map to Klaviyo List').item.json.lifecycle_stage }}\nKlaviyo list: {{ $('Map to Klaviyo List').item.json.list_name }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "#crm-sync"
        },
        "otherOptions": {}
      },
      "typeVersion": 2.2
    },
    {
      "id": "e04b57b1-e44a-447a-82c7-9e08d4bfc74d",
      "name": "Log Sync to Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2112,
        384
      ],
      "parameters": {
        "columns": {
          "value": {
            "Name": "={{ $('Map to Klaviyo List').item.json.first_name + ' ' + $('Map to Klaviyo List').item.json.last_name }}",
            "Email": "={{ $('Map to Klaviyo List').item.json.email }}",
            "Status": "Synced",
            "Company": "={{ $('Map to Klaviyo List').item.json.company }}",
            "Timestamp": "={{ $('Map to Klaviyo List').item.json.timestamp }}",
            "Klaviyo List": "={{ $('Map to Klaviyo List').item.json.list_name }}",
            "HubSpot Stage": "={{ $('Map to Klaviyo List').item.json.lifecycle_stage }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Klaviyo Sync Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "5f64bdb9-48af-46ea-84b0-76dad56d73c3",
  "connections": {
    "Add to Klaviyo List": {
      "main": [
        [
          {
            "node": "Notify Sync Complete",
            "type": "main",
            "index": 0
          },
          {
            "node": "Log Sync to Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Map to Klaviyo List": {
      "main": [
        [
          {
            "node": "Create Klaviyo Profile",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Klaviyo Profile": {
      "main": [
        [
          {
            "node": "Add to Klaviyo List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Receive HubSpot Contact": {
      "main": [
        [
          {
            "node": "Configure Mapping and Settings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Full HubSpot Contact": {
      "main": [
        [
          {
            "node": "Map to Klaviyo List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configure Mapping and Settings": {
      "main": [
        [
          {
            "node": "Fetch Full HubSpot Contact",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}