{
  "name": "Workflow for two-way sync between Airtable and HubSpot",
  "nodes": [
    {
      "id": "a5a2f6d8-ce49-44f4-87b5-6af910b648a3",
      "name": "get domain",
      "type": "n8n-nodes-base.set",
      "position": [
        816,
        0
      ]
    },
    {
      "id": "91594f3f-855d-48cc-810a-efb7431dc7fa",
      "name": "Search company",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        1056,
        0
      ]
    },
    {
      "id": "13fa19e4-67e3-498d-91cd-52e8da8cab95",
      "name": "Create a company",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        1456,
        272
      ]
    },
    {
      "id": "6d158464-71dc-41c7-b1e3-bdd857c40060",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        1680,
        -32
      ]
    },
    {
      "id": "2a792790-07c4-4101-846e-fe8d6fe37c5b",
      "name": "Create or update a contact",
      "type": "n8n-nodes-base.hubspot",
      "position": [
        1952,
        -48
      ]
    },
    {
      "id": "af848f9f-b36b-41fe-865a-59c805048b37",
      "name": "Sync back",
      "type": "n8n-nodes-base.airtable",
      "position": [
        2224,
        -64
      ]
    },
    {
      "id": "e48f0037-5055-4059-8616-7ea6bb39d849",
      "name": "Report Failure",
      "type": "n8n-nodes-base.airtable",
      "position": [
        2464,
        224
      ]
    },
    {
      "id": "d276bbe1-be3a-4bf2-9c49-83e57d7649de",
      "name": "change status to Syncing...",
      "type": "n8n-nodes-base.airtable",
      "position": [
        576,
        0
      ]
    },
    {
      "id": "d9d0b7be-58f2-494a-80d9-6dd58519262f",
      "name": "If company exists",
      "type": "n8n-nodes-base.if",
      "position": [
        1280,
        0
      ]
    },
    {
      "id": "878ae011-4714-4e8c-b19b-f65cb8615a5b",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -192,
        368
      ]
    },
    {
      "id": "43d1bacc-9974-48ce-8db7-50c31d43ec03",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        336,
        368
      ]
    },
    {
      "id": "f387807a-1ec5-4c9a-bd8d-6d67a2ac278a",
      "name": "🎉All Records Completed!🎉",
      "type": "n8n-nodes-base.noOp",
      "position": [
        544,
        -256
      ]
    },
    {
      "id": "9e72bd78-4377-4767-8077-6c8c89fd0cec",
      "name": "👍Done! Going for next record",
      "type": "n8n-nodes-base.noOp",
      "position": [
        3024,
        320
      ]
    },
    {
      "id": "eec0e289-05e3-4813-9dc6-d88a3e922fd4",
      "name": "👎Failed! Going for next record1",
      "type": "n8n-nodes-base.noOp",
      "position": [
        2688,
        288
      ]
    },
    {
      "id": "38da10fa-535e-4d18-8c88-27058581f3b9",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -976,
        -48
      ],
      "parameters": {
        "width": 576,
        "height": 896,
        "content": "## 🚀 Welcome! \n## Batch-sync approved leads from Airtable to HubSpot\n\nThis template solves a common business problem: **how to get leads from a simple \"control panel\" (Airtable) into your CRM (HubSpot"
      }
    },
    {
      "id": "0c1834b4-8429-4e92-8c86-6164ac8acae0",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -384,
        368
      ],
      "parameters": {
        "width": 304,
        "height": 480,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n## Step 1: Set Your Schedule\n\nThis is a **polling trigger**. It checks for new leads on a timer. I've set it to **20 seconds** for testing.\n\n> **Your Action:**\n> For a real-world setup, y"
      }
    },
    {
      "id": "4494c108-2a65-4205-96ee-7f7408350526",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        368
      ],
      "parameters": {
        "width": 304,
        "height": 480,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n## Step 2: Configure Airtable\n\nThis node **fetches a batch of up to 50 leads** from the **\"👍 Ready to Sync\"** view.\n\n> **Your Action:**\n> 1.  Select your Airtable credential.\n> 2.  In the "
      }
    },
    {
      "id": "a177f922-1888-49ff-a8a5-0b73eba18f8c",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        256,
        368
      ],
      "parameters": {
        "width": 464,
        "height": 480,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n## Logic: The Batch Engine ⚙️\n\nThis is the *engine* of your batch system. It takes the 50 records from the previous step and processes them **one at a time**.\n\n* The **top output** (`No It"
      }
    },
    {
      "id": "aa3f39c3-df1b-4ed2-adba-18c7cae0c121",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        256,
        -544
      ],
      "parameters": {
        "width": 464,
        "height": 464,
        "content": "## All Done!\n\nThis node marks the end of a *poll cycle* where no records (or no more records) were found.\n\nThe workflow will now wait for the next `Schedule Trigger`."
      }
    },
    {
      "id": "a69b124c-16a9-4561-8da1-b0fa14b99e70",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        256,
        -32
      ],
      "parameters": {
        "width": 464,
        "height": 384,
        "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n## Logic: Lock the Record 🔒\n\nThis is a professional safeguard. It immediately sets the *current* record's status to **'🔄 Syncing...'**\n\n**Why?** This prevents the *next* poll cycle from g"
      }
    },
    {
      "id": "419a0292-5128-4a7c-83f1-54271c72fad8",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        752,
        -288
      ],
      "parameters": {
        "width": 224,
        "height": 448,
        "content": "## Logic: Helper Node\n\nThis node simply takes the email (`user@company.com`) and splits it to keep *only* the domain (`company.com`).\n\nThis domain is used in the next step to search for the company."
      }
    },
    {
      "id": "180f5e90-932e-4aa5-8369-51bd5c5b3fa1",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        992,
        -416
      ],
      "parameters": {
        "width": 256,
        "height": 576,
        "content": "## Step 3: Configure HubSpot\n\nThis is the *first* HubSpot node, so you must set your credential here.\n\n> **Your Action:**\n> 1.  Select your HubSpot Private App credential.\n\n---\n### This Node's Logic ("
      }
    },
    {
      "id": "501e1fab-9ae2-4cfc-bfa1-2668af24b630",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1264,
        -512
      ],
      "parameters": {
        "width": 304,
        "height": 960,
        "content": "## Logic: Check if Company Was Found\n\nThe `Search company` node is configured to output a *company object* directly (not a \"total\" or \"results\" list).\n>\n> * **If a company is found:** It outputs the o"
      }
    },
    {
      "id": "e433f6b3-b2b6-49db-8423-7debfbbd2520",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1584,
        -416
      ],
      "parameters": {
        "width": 272,
        "height": 576,
        "content": "## Logic: Combine Paths\n\nThis node brings the `true` (Find) and `false` (Create) paths back together.\n\nAfter this node, the workflow has a single, valid `companyId` to work with, no matter which path "
      }
    },
    {
      "id": "a5b9f18c-20b8-4694-875e-19063ce94795",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1872,
        -288
      ],
      "parameters": {
        "width": null,
        "height": 448,
        "content": "## Logic: Create/Update Contact 🧑‍💼\n\nThis node uses the contact's email as a unique key to create or update their record."
      }
    },
    {
      "id": "09540b53-61b4-40d2-8773-62a74bba2ed5",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2128,
        -256
      ],
      "parameters": {
        "width": 256,
        "height": 416,
        "content": "## Success: Sync to Airtable ✅\n\nThis is the final \"feedback loop\" for a successful run."
      }
    },
    {
      "id": "5c302134-cb3f-4477-9b3a-a897d9930fbc",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2400,
        -192
      ],
      "parameters": {
        "width": null,
        "height": 640,
        "content": "## Error Handling ❌\n\nThis node *only* runs if something fails in the main sync. It updates the Airtable row, sets `Status` to **'❌ Error'**, and posts the error message in the **'Note'** field."
      }
    },
    {
      "id": "3f42c342-5dfb-40ae-a5fd-4d9521b7bb35",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -384,
        -48
      ],
      "parameters": {
        "width": 1120,
        "height": 896,
        "content": "## Get Data \n"
      }
    },
    {
      "id": "fff64536-4dab-4072-8621-8ee467eaf05b",
      "name": "get 👍Ready to Sync",
      "type": "n8n-nodes-base.airtable",
      "position": [
        48,
        368
      ]
    },
    {
      "id": "75a7b2a8-84e0-4142-82bb-4fb36e96b07a",
      "name": "Sticky Note14",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        752,
        -576
      ],
      "parameters": {
        "width": 672,
        "height": 1424,
        "content": "## PROCESS...\n"
      }
    },
    {
      "id": "a22fac4c-bc93-4471-b82f-8ce36de1af3d",
      "name": "Sticky Note15",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1440,
        -576
      ],
      "parameters": {
        "width": 1216,
        "height": 1424,
        "content": "## OUTPUT\n"
      }
    },
    {
      "id": "cfe8b8b8-5828-4292-9250-eb4e1f49ae45",
      "name": "Sticky Note16",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2672,
        -576
      ],
      "parameters": {
        "width": 672,
        "height": 1424,
        "content": "## GOING BACK TO START THE NEXT⬅️"
      }
    }
  ],
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Create or update a contact",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Report Failure",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sync back": {
      "main": [
        [
          {
            "node": "👍Done! Going for next record",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Report Failure",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "get domain": {
      "main": [
        [
          {
            "node": "Search company",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Report Failure": {
      "main": [
        [
          {
            "node": "👎Failed! Going for next record1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search company": {
      "main": [
        [
          {
            "node": "If company exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "🎉All Records Completed!🎉",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "change status to Syncing...",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create a company": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ],
        [
          {
            "node": "Report Failure",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "get 👍Ready to Sync",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If company exists": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Create a company",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "get 👍Ready to Sync": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create or update a contact": {
      "main": [
        [
          {
            "node": "Sync back",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Report Failure",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "change status to Syncing...": {
      "main": [
        [
          {
            "node": "get domain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "👍Done! Going for next record": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "👎Failed! Going for next record1": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}