{
  "id": "k6EKW8IQZqkzYe9m",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Collect keyword cluster by URL in Google Sheets with DataForSEO",
  "tags": [],
  "nodes": [
    {
      "id": "a8c9abe6-a148-45fb-a28d-fcacadaadf8e",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        224,
        304
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 9,
              "weeksInterval": 2
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "29aebb97-4fef-440e-9daf-158ea953e085",
      "name": "Create sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1312,
        304
      ],
      "parameters": {
        "title": "={{ $json.url }}",
        "options": {},
        "operation": "create",
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1a0stVebKWNIEkjf-R8yoVOByjqLDNASkILarnq4meLM",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1a0stVebKWNIEkjf-R8yoVOByjqLDNASkILarnq4meLM/edit?usp=drivesdk",
          "cachedResultName": "URLs claster - output"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7,
      "alwaysOutputData": true
    },
    {
      "id": "a53daec5-9604-46a4-88ae-8dae94e5aea0",
      "name": "Append row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1984,
        160
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "Keyword",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Keyword",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [
            "Keyword"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Normalize URL').item.json.url }}"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1a0stVebKWNIEkjf-R8yoVOByjqLDNASkILarnq4meLM",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1a0stVebKWNIEkjf-R8yoVOByjqLDNASkILarnq4meLM/edit?usp=drivesdk",
          "cachedResultName": "URLs claster - output"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "1eb45578-e218-422d-b2de-9b1655e9e684",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        2208,
        304
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "ce222f58-f963-47bb-acf9-59a5bc78b871",
      "name": "Normalize URL",
      "type": "n8n-nodes-base.code",
      "position": [
        1088,
        304
      ],
      "parameters": {
        "jsCode": "let url = $input.first().json.Target;\n\nreturn {\n  url: url.trim()\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "83bf9864-3dc6-4fcd-b5c7-9c9424eb8603",
      "name": "Prepare data for GS",
      "type": "n8n-nodes-base.set",
      "position": [
        3008,
        304
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={\n\"Keyword\": \"{{ $json.keyword_data.keyword }}\",\n\"Run Date\": \"{{ $now.format('yyyy-MM-dd') }}\",\n\"Location\": \"{{ $('Get ranked keywords').item.json.tasks[0].data.location_name }}\",\n\"Language\": \"{{ $('Get ranked keywords').item.json.tasks[0].data.language_name }}\",\n\"Rank Group\": {{ $json.ranked_serp_element.serp_item.rank_group }},\n\"Rank Absolute\": {{ $json.ranked_serp_element.serp_item.rank_absolute }},\n\"Search Volume\": {{ $json.keyword_data.keyword_info.search_volume }},\n\"Keyword Difficulty\": {{ $json.keyword_data.keyword_properties.keyword_difficulty }},\n\"CPC\": {{ $json.keyword_data.keyword_info.cpc }},\n\"Competition\": {{ $json.keyword_data.keyword_info.competition_level }},\n\"Search Intent\": \"{{ $json.keyword_data.search_intent_info.main_intent }}\",\n\"Result Type\": \"{{ $json.ranked_serp_element.serp_item.type }}\",\n\"ETV\": {{ $json.ranked_serp_element.serp_item.etv }},\n\"SE Type\": \"{{ $json.keyword_data.keyword_info.se_type }}\",\n\"Data Source\": \"dataforseo_labs_google_ranked_keywords_live\"\n}\n "
      },
      "typeVersion": 3.4
    },
    {
      "id": "cd34eb62-88fd-4d91-bc1a-8511c058cc52",
      "name": "Prepare columns data for GS",
      "type": "n8n-nodes-base.set",
      "position": [
        1760,
        160
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={\n\"Keyword\": \"\"\n\"Run Date\": \"\",\n\"Location\": \"\",\n\"Language\": \"\",\n\"Rank Group\": \"\",\n\"Rank Absolute\": \"\",\n\"Search Volume\": \"\",\n\"Keyword Difficulty\": \"\",\n\"CPC\": \"\",\n\"Competition\":\"\",\n\"Search Intent\": \"\",\n\"Result Type\": \"\",\n\"ETV\":\"\",\n\"SE Type\": \"\",\n\"Data Source\": \"\"\n}\n \n "
      },
      "typeVersion": 3.4
    },
    {
      "id": "579f73e9-7c0e-472a-972a-dbc759a2b68a",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1264,
        80
      ],
      "parameters": {
        "color": 6,
        "width": 1104,
        "height": 384,
        "content": "## Create a new sheet if it doesn't exist\nCreate or select a Google Sheets connection. Select output spreadsheet."
      },
      "typeVersion": 1
    },
    {
      "id": "a89c2f37-f1b9-42a8-8d09-43e7c2d24656",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2384,
        80
      ],
      "parameters": {
        "color": 6,
        "width": 948,
        "height": 384,
        "content": "## Get Ranked Keywords with DataForSEO and save it to Google Sheet\nCreate or select a Google Sheets connection, and select output spreadsheet.\nCreate or select a DataForSEO connection."
      },
      "typeVersion": 1
    },
    {
      "id": "a785f754-9336-4d38-95a3-0f578fa6db5b",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        384,
        80
      ],
      "parameters": {
        "color": 6,
        "width": 432,
        "height": 384,
        "content": "## Get active URLs from the input in Google Sheets\nCreate or select a Google Sheets connection. Select the input table with URLs. The sheet must have the same columns as in [this Example](https://docs.google.com/spreadsheets/d/1eyGnMu910kaEPfRGj2mHLVsrRb57CXKhFCmbf9tCBHw/edit?usp=sharing)."
      },
      "typeVersion": 1
    },
    {
      "id": "518ca7d1-7e17-4fa4-bb8d-97c68e954905",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        -368
      ],
      "parameters": {
        "width": 1296,
        "height": 368,
        "content": "This workflow automatically retrieves a list of URLs, collects up to 100 organic keywords each URL ranks for on Google using the DataForSEO Labs API, and saves the results with all key metrics into a historical Google Sheets dataset.\n\n## How it works\n1. Triggers on your preferred schedule or manually.\n2. Fetches URLs from your input in Google Sheets.\n3. Check the top-100 ranked keywords on for your URLs using the DataForSEO Labs API.\n4. Creates a dedicated sheet for each URL, saves SEO metrics from the API response, such as keyword, ranking positions, search volume, keyword difficulty, CPC, competition, search intent, and more. \n5. Adds new columns for each date of the run, creating a historical data record in Google Sheets.\n\n## Setup steps\n\n1. Create or select your DataForSEO connection (use [your API login and password](https://app.dataforseo.com/api-access)).\n2. Create or select a Google Sheets connection for the input and output spreadsheets.\n3. Prepare the input sheet with the list of URLs.\n4. Set the preferred workflow schedule."
      },
      "typeVersion": 1
    },
    {
      "id": "e605f98a-4091-4273-b039-cfcf98eb159f",
      "name": "Get URLs",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        448,
        304
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1eyGnMu910kaEPfRGj2mHLVsrRb57CXKhFCmbf9tCBHw/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1eyGnMu910kaEPfRGj2mHLVsrRb57CXKhFCmbf9tCBHw",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1eyGnMu910kaEPfRGj2mHLVsrRb57CXKhFCmbf9tCBHw/edit?usp=drivesdk",
          "cachedResultName": "URLs claster"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "58440554-18eb-4e9a-9e80-79de90a39c74",
      "name": "Get ranked keywords",
      "type": "n8n-nodes-dataforseo.dataForSeoLabsApi",
      "position": [
        2416,
        304
      ],
      "parameters": {
        "limit": "={{ $('Loop Over Items (each URL)').item.json.Limit || 100 }}",
        "operation": "get-ranked-keywords",
        "target_any": "={{ $('Loop Over Items (each URL)').item.json.Target }}",
        "language_name": "={{ $('Loop Over Items (each URL)').item.json['Language name'] || 'English' }}",
        "location_name": "={{ $('Loop Over Items (each URL)').item.json['Location name'] || 'United States' }}"
      },
      "credentials": {
        "dataForSeoApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "1c43b35d-1366-44dd-b183-98faaec6f605",
      "name": "Append row in sheet1",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3216,
        304
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Normalize URL').item.json.url }}"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1a0stVebKWNIEkjf-R8yoVOByjqLDNASkILarnq4meLM",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1a0stVebKWNIEkjf-R8yoVOByjqLDNASkILarnq4meLM/edit?usp=drivesdk",
          "cachedResultName": "URLs claster - output"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "b9612850-1915-4a23-8828-086d916da404",
      "name": "Loop Over Items (each URL)",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        880,
        304
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "80c85c07-4da2-4c2d-8d24-b26fa916ca62",
      "name": "Split out (items)",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        2832,
        304
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "tasks[0].result[0].items"
      },
      "typeVersion": 1
    },
    {
      "id": "d2355a78-8787-4d94-921a-a46474f24206",
      "name": "Filter",
      "type": "n8n-nodes-base.filter",
      "position": [
        2624,
        304
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "866070df-19a1-44ee-9bbf-ef858289adf4",
              "operator": {
                "type": "array",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.tasks[0].result[0].items }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "91cd800c-ad19-4939-acca-ffac87aa2e16",
      "name": "Filter (only active)",
      "type": "n8n-nodes-base.filter",
      "position": [
        656,
        304
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "31a61fed-0f56-42f5-94bd-0216e3a8b592",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.Status }}",
              "rightValue": "Active"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "b4ecb11d-e3ae-452e-a1c8-ef7f15260a1e",
      "name": "If a new sheet created",
      "type": "n8n-nodes-base.if",
      "position": [
        1520,
        304
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "fd006d00-db1b-4407-a2ef-6185a3626aa9",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.spreadsheetId }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "e093eca1-92d6-424b-b632-dcb5c5c9c38e",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Get ranked keywords",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter": {
      "main": [
        [
          {
            "node": "Split out (items)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get URLs": {
      "main": [
        [
          {
            "node": "Filter (only active)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create sheet": {
      "main": [
        [
          {
            "node": "If a new sheet created",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize URL": {
      "main": [
        [
          {
            "node": "Create sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get URLs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split out (items)": {
      "main": [
        [
          {
            "node": "Prepare data for GS",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append row in sheet": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get ranked keywords": {
      "main": [
        [
          {
            "node": "Filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare data for GS": {
      "main": [
        [
          {
            "node": "Append row in sheet1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append row in sheet1": {
      "main": [
        [
          {
            "node": "Loop Over Items (each URL)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter (only active)": {
      "main": [
        [
          {
            "node": "Loop Over Items (each URL)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If a new sheet created": {
      "main": [
        [
          {
            "node": "Prepare columns data for GS",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Loop Over Items (each URL)": {
      "main": [
        [],
        [
          {
            "node": "Normalize URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare columns data for GS": {
      "main": [
        [
          {
            "node": "Append row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}