{
  "id": "jpviET9waC9J5cmy",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "BuiltWith To Google Sheets",
  "tags": [],
  "nodes": [
    {
      "id": "b91b2e44-7fa5-44ce-a328-e6416bc6aed9",
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        0,
        0
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "014ab620-9f80-40af-85ba-13a606021bfa",
      "name": "Read Domains from Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        220,
        0
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Hs9LcBpC-kaGgD_QjkkqBEJzDeAd85RW_L1fXTYEdCA/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1Hs9LcBpC-kaGgD_QjkkqBEJzDeAd85RW_L1fXTYEdCA",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Hs9LcBpC-kaGgD_QjkkqBEJzDeAd85RW_L1fXTYEdCA/edit?usp=drivesdk",
          "cachedResultName": "BuiltWith Domain"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "07215599-c91a-474c-935f-c94c34e8b9b9",
      "name": "Fetch detail via BuiltWith",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        480,
        0
      ],
      "parameters": {
        "url": "https://api.builtwith.com/v21/api.json",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "KEY",
              "value": "YOUR_API_KEY"
            },
            {
              "name": "LOOKUP",
              "value": "={{ $json.Domain }}"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "49ec52b1-5f97-4871-ac6c-564fa444b7ec",
      "name": "Extract Tech Stack Info",
      "type": "n8n-nodes-base.code",
      "position": [
        700,
        0
      ],
      "parameters": {
        "jsCode": "const result = $json.Results?.[0];\nconst domain = result?.Lookup || null;\nconst path = result?.Result?.Paths?.[0];\nconst url = path?.Url || null;\n\nlet extracted = null;\n\n// Loop through Groups to find the first available Tech entry\nfor (const group of path?.Groups || []) {\n  const category = group.Name;\n  const tech = group.Tech?.[0];\n  \n  if (tech) {\n    extracted = {\n      Technology: tech.Name,\n      Category: category,\n      \"First Detected\": tech.FirstDetected,\n      \"Last Detected\": tech.LastDetected,\n      Domain: domain,\n      URL: url\n    };\n    break; // Stop after first match\n  }\n}\n\nreturn extracted ? [extracted] : [];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "e2b7063b-614f-4ded-a883-bffc4bcb6c3c",
      "name": "Update Google Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1020,
        0
      ],
      "parameters": {
        "columns": {
          "value": {
            "URL": "={{ $json.URL }}",
            "Category": "={{ $json.Category }}",
            "Technology": "={{ $json.Technology }}",
            "row_number": "={{ $('Read Domains from Google Sheets').item.json.row_number }}",
            "Last Detected": "={{ $json[\"Last Detected\"] }}",
            "First Detected": "={{ $json[\"First Detected\"] }}"
          },
          "schema": [
            {
              "id": "Domain",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Domain",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Technology",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Technology",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Category",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Category",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "First Detected",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "First Detected",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Last Detected",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Last Detected",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "URL",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "row_number"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Hs9LcBpC-kaGgD_QjkkqBEJzDeAd85RW_L1fXTYEdCA/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1Hs9LcBpC-kaGgD_QjkkqBEJzDeAd85RW_L1fXTYEdCA",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Hs9LcBpC-kaGgD_QjkkqBEJzDeAd85RW_L1fXTYEdCA/edit?usp=drivesdk",
          "cachedResultName": "BuiltWith Domain"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "11d4cd39-98d4-4b0f-8159-035bac593f39",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -40,
        -800
      ],
      "parameters": {
        "color": 6,
        "width": 420,
        "height": 1000,
        "content": "## \ud83e\udde9 **Section 1: Input Collection**\n\n\ud83d\udcc4\u27a1\ufe0f\ud83d\udce4\n**Nodes:**\n\n* `\ud83d\uddb1\ufe0f Manual Trigger`\n* `\ud83d\udcd7 Read Domains from Google Sheets`\n\n---\n\n### \ud83d\udd39 What it does:\n\n* The workflow starts **when you click \"Test workflow\"** (manual trigger). This is useful for testing before setting up a schedule.\n* Then it connects to a **Google Sheet**, which contains a list of domains (e.g., `webflow.com`, `shopify.com`) you want to analyze.\n\n### \ud83d\udcda How it works:\n\n* You\u2019ve connected your Google Sheets account.\n* It reads all rows from a specific sheet (e.g., a tab called `Domains`).\n* Each row should include at least one column like `Domain`.\n\n### \ud83d\udca1 Beginner Tips:\n\n* Want to analyze other domains? Just paste them into the Google Sheet.\n* You can automate this by replacing the manual trigger with a `Cron` node to run every day, week, or month.\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e8ec39a6-ac8e-40ab-abc6-835600ef9c09",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        420,
        -900
      ],
      "parameters": {
        "color": 7,
        "width": 440,
        "height": 1100,
        "content": "## \ud83c\udf0d **Section 2: Tech Stack Lookup**\n\n\ud83d\udd0d\ud83c\udf10\u27a1\ufe0f\ud83e\udde0\n**Nodes:**\n\n* `\ud83c\udf10 Fetch Tech Stack from BuiltWith`\n* `\ud83e\udde0 Extract Tech Stack Info (Function node)`\n\n---\n\n### \ud83d\udd39 What it does:\n\n* For each domain, it sends an HTTP GET request to the **BuiltWith API** to fetch that site's detected technologies.\n* The **Code (Function)** node then parses the complex response and extracts only what you care about:\n\n  * `Technology` \ud83d\udee0\ufe0f\n  * `Category` \ud83d\udce6\n  * `First Detected` \ud83d\udd50\n  * `Last Detected` \u231b\n  * `Domain` \ud83c\udf10\n  * `URL` \ud83d\udd17\n\n### \ud83e\udde0 How it works:\n\n* BuiltWith returns a rich JSON structure with all detected tech.\n* Your function loops through it and pulls **just one matching technology** per domain (to keep it simple).\n* This makes it easy to update a single row in your sheet.\n\n### \ud83d\udca1 Beginner Tips:\n\n* Want **all technologies** per domain? Modify the function to return multiple results per input.\n* Make sure to handle **API limits** if you\u2019re processing many domains\u2014add delays using the `Wait` node if needed.\n\n---\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "926c3af0-de90-43a9-a2c8-efe838548e09",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        900,
        -780
      ],
      "parameters": {
        "color": 5,
        "width": 360,
        "height": 980,
        "content": "# \ud83d\udcca **Section 3: Output to Google Sheets**\n\n\ud83d\udce5\ud83d\udcdd\n**Node:**\n\n* `\ud83d\udcd7 Update Google Sheet with Tech Stack`\n\n---\n\n### \ud83d\udd39 What it does:\n\n* Takes the extracted data and **writes it back to the original sheet**.\n* Fills in columns like:\n\n  * `Technology`\n  * `Category`\n  * `First Detected`\n  * `Last Detected`\n\n### \u270d\ufe0f How it works:\n\n* It matches the correct row using something like a `row_number` or primary key.\n* Then it updates that row with the extracted tech stack info.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e00e4ddd-e314-4562-9f3f-df18bb27949a",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1620,
        -800
      ],
      "parameters": {
        "color": 4,
        "width": 1300,
        "height": 320,
        "content": "=======================================\n            WORKFLOW ASSISTANCE\n=======================================\nFor any questions or support, please contact:\n    Yaron@nofluff.online\n\nExplore more tips and tutorials here:\n   - YouTube: https://www.youtube.com/@YaronBeen/videos\n   - LinkedIn: https://www.linkedin.com/in/yaronbeen/\n=======================================\n"
      },
      "typeVersion": 1
    },
    {
      "id": "28a6ebbd-74ad-47f4-9ad8-354b68316953",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1620,
        -460
      ],
      "parameters": {
        "color": 4,
        "width": 1289,
        "height": 2818,
        "content": "## \u2699\ufe0f **Workflow Overview: Scrape BuiltWith Tech Data into Google Sheets**\n\nThis automation does three main things:\n\n1. \ud83d\udce5 **Reads domains from Google Sheets**\n2. \ud83c\udf10 **Fetches tech stack data from BuiltWith**\n3. \ud83d\udce4 **Updates Google Sheets with the results**\n\n---\n\n## \ud83e\udde9 **Section 1: Input Collection**\n\n\ud83d\udcc4\u27a1\ufe0f\ud83d\udce4\n**Nodes:**\n\n* `\ud83d\uddb1\ufe0f Manual Trigger`\n* `\ud83d\udcd7 Read Domains from Google Sheets`\n\n---\n\n### \ud83d\udd39 What it does:\n\n* The workflow starts **when you click \"Test workflow\"** (manual trigger). This is useful for testing before setting up a schedule.\n* Then it connects to a **Google Sheet**, which contains a list of domains (e.g., `webflow.com`, `shopify.com`) you want to analyze.\n\n### \ud83d\udcda How it works:\n\n* You\u2019ve connected your Google Sheets account.\n* It reads all rows from a specific sheet (e.g., a tab called `Domains`).\n* Each row should include at least one column like `Domain`.\n\n### \ud83d\udca1 Beginner Tips:\n\n* Want to analyze other domains? Just paste them into the Google Sheet.\n* You can automate this by replacing the manual trigger with a `Cron` node to run every day, week, or month.\n\n---\n\n## \ud83c\udf0d **Section 2: Tech Stack Lookup**\n\n\ud83d\udd0d\ud83c\udf10\u27a1\ufe0f\ud83e\udde0\n**Nodes:**\n\n* `\ud83c\udf10 Fetch Tech Stack from BuiltWith`\n* `\ud83e\udde0 Extract Tech Stack Info (Function node)`\n\n---\n\n### \ud83d\udd39 What it does:\n\n* For each domain, it sends an HTTP GET request to the **BuiltWith API** to fetch that site's detected technologies.\n* The **Code (Function)** node then parses the complex response and extracts only what you care about:\n\n  * `Technology` \ud83d\udee0\ufe0f\n  * `Category` \ud83d\udce6\n  * `First Detected` \ud83d\udd50\n  * `Last Detected` \u231b\n  * `Domain` \ud83c\udf10\n  * `URL` \ud83d\udd17\n\n### \ud83e\udde0 How it works:\n\n* BuiltWith returns a rich JSON structure with all detected tech.\n* Your function loops through it and pulls **just one matching technology** per domain (to keep it simple).\n* This makes it easy to update a single row in your sheet.\n\n### \ud83d\udca1 Beginner Tips:\n\n* Want **all technologies** per domain? Modify the function to return multiple results per input.\n* Make sure to handle **API limits** if you\u2019re processing many domains\u2014add delays using the `Wait` node if needed.\n\n---\n\n## \ud83d\udcca **Section 3: Output to Google Sheets**\n\n\ud83d\udce5\ud83d\udcdd\n**Node:**\n\n* `\ud83d\udcd7 Update Google Sheet with Tech Stack`\n\n---\n\n### \ud83d\udd39 What it does:\n\n* Takes the extracted data and **writes it back to the original sheet**.\n* Fills in columns like:\n\n  * `Technology`\n  * `Category`\n  * `First Detected`\n  * `Last Detected`\n\n### \u270d\ufe0f How it works:\n\n* It matches the correct row using something like a `row_number` or primary key.\n* Then it updates that row with the extracted tech stack info.\n\n### \ud83d\udca1 Beginner Tips:\n\n* Add more columns like `Confidence`, `Data Source`, or `Notes` if you want to enrich your research.\n* Use this sheet for:\n\n  * \ud83d\udcbc Lead qualification\n  * \ud83d\udcca Market analysis\n  * \ud83d\ude80 Tech product targeting\n\n---\n\n## \ud83c\udfaf Final Thoughts\n\n\ud83d\udd01 This automation turns a **manual and tedious research task** into a repeatable, scalable, and accurate process. By connecting **Google Sheets + BuiltWith + n8n**, you can:\n\n\u2705 Automatically analyze websites\n\u2705 Store structured data for marketing or sales\n\u2705 Scale your intelligence gathering with just a few clicks\n\n---\n\n\n"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "f2928e0a-050f-4b50-b11b-7435cc08265c",
  "connections": {
    "Manual Trigger": {
      "main": [
        [
          {
            "node": "Read Domains from Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Tech Stack Info": {
      "main": [
        [
          {
            "node": "Update Google Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch detail via BuiltWith": {
      "main": [
        [
          {
            "node": "Extract Tech Stack Info",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Domains from Google Sheets": {
      "main": [
        [
          {
            "node": "Fetch detail via BuiltWith",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}