This workflow corresponds to n8n.io template #11216 — we link there as the canonical source.
This workflow follows the Google Sheets → HTTP Request recipe pattern — see all workflows that pair these two integrations.
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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "e6f42b9f-060d-4fee-9c8b-def8beba5ad3",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2304,
4160
],
"parameters": {
"color": 4,
"width": 336,
"height": 256,
"content": "## \ud83d\udca5 Run to find your n8n's server IP\n"
},
"typeVersion": 1
},
{
"id": "31aa849e-e6ea-4595-b566-3233a470bb7e",
"name": "Find n8n's IP",
"type": "n8n-nodes-base.httpRequest",
"position": [
-2256,
4256
],
"parameters": {
"url": "https://api.ipify.org?format=jso",
"options": {}
},
"typeVersion": 4.3
},
{
"id": "42879ff1-b096-419a-a65f-ef69ee02bb29",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2304,
3440
],
"parameters": {
"width": 426,
"height": 688,
"content": "## \ud83d\udd0d Low competition keyword finder\n\n**What it does:**\nFinds untapped keyword opportunities by analyzing keyword suggestions, checking their difficulty, and examining SERP competition. \n\n**How it works:**\n1. Reads seed keyword or domain from Google Sheets\n2. Gets relevant keyword ideas \n3. Checks ranking difficulty for each keyword \n4. Analyzes SERP results for top opportunities\n5. Filters for low-competition keywords (KD < 30)\n6. Writes results back to Google Sheets\n\n**Setup Requirements:**\n- DataForSEO account with API access\n- Google Sheets: duplicate [this template](https://docs.google.com/spreadsheets/d/13ioeuFckLX4qEesbJwQ4C04I0-TPppdMoJVKEAPXCSI/edit?usp=sharing). You can create your own.\n\nData Captured:\n\n- Keyword & Search Volume\n- Monthly/Quarterly/Yearly Trends\n- Keyword Difficulty (0-100)\n- Search Intent (main + foreign)\n- Average Backlinks\n- Last Updated Time\n- SE Type & Location/Language codes"
},
"typeVersion": 1
},
{
"id": "161964df-e615-4999-b0f8-a74c591a2813",
"name": "Read Seeds",
"type": "n8n-nodes-base.googleSheets",
"position": [
-1488,
3680
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "id",
"value": "1232412"
},
"documentId": {
"__rl": true,
"mode": "url",
"value": "https://docs.google.com/spreadsheets/d/XX/edit?usp=drivesdkXXXXXXXX"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4
},
{
"id": "2563a5c1-ee84-4f65-b066-f84676d6a792",
"name": "Format Data",
"type": "n8n-nodes-base.code",
"position": [
-336,
3712
],
"parameters": {
"jsCode": "const keywordsData = $input.first().json;\nconst difficultyData = $input.last().json;\n\nconst keywords = keywordsData.tasks[0].result[0].items;\nconst difficulties = difficultyData.tasks[0].result[0].items;\n\nconst difficultyMap = {};\ndifficulties.forEach(item => {\n difficultyMap[item.keyword] = item.keyword_difficulty;\n});\n\nconst rows = keywords.map(kw => ({\n seed: keywordsData.tasks[0].data.target,\n keywords: kw.keyword,\n 'Search Volume': kw.keyword_info.search_volume || 0,\n 'Trend Monthly': kw.keyword_info.search_volume_trend?.monthly ?? null,\n 'Trend Quarterly': kw.keyword_info.search_volume_trend?.quarterly ?? null,\n 'Trend Yearly': kw.keyword_info.search_volume_trend?.yearly ?? null,\n 'SE Type': kw.se_type,\n 'Main Intent': kw.search_intent_info?.main_intent || '',\n 'Foreign Intent': kw.search_intent_info?.foreign_intent?.join(', ') || '',\n 'Last Updated Time': kw.keyword_info.last_updated_time,\n 'Backlinks': kw.avg_backlinks_info?.backlinks || 0,\n 'Keyword Difficulty': difficultyMap[kw.keyword] ?? null\n}));\n\nreturn rows.map(row => ({ json: row }));"
},
"typeVersion": 2
},
{
"id": "b0e0e5a1-d4df-4262-8b5c-366a40ac5d6f",
"name": "Collect All Results",
"type": "n8n-nodes-base.aggregate",
"position": [
-96,
3712
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData"
},
"typeVersion": 1
},
{
"id": "305d419d-efd5-41c9-8c6a-c1f39509e870",
"name": "Write to Sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
-1056,
3472
],
"parameters": {
"columns": {
"value": {
"SE Type": "={{ $json['SE Type'] }}",
"keywords": "={{ $json.keywords }}",
"Backlinks": "={{ $json.Backlinks }}",
"Main Intent": "={{ $json['Main Intent'] }}",
"Trend Yearly": "={{ $json['Trend Yearly'] }}",
"Search Volume": "={{ $json['Search Volume'] }}",
"Trend Monthly": "={{ $json['Trend Monthly'] }}",
"Foreign Intent": "={{ $json['Foreign Intent'] }}",
"Trend Quarterly": "={{ $json['Trend Quarterly'] }}",
"Last Updated Time": "={{ $json['Last Updated Time'] }}",
"Keyword Difficulty": "={{ $json['Keyword Difficulty'] }}"
},
"schema": [
{
"id": "keywords",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "keywords",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Search Volume",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Search Volume",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Trend Monthly",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Trend Monthly",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Trend Quarterly",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Trend Quarterly",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Trend Yearly",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Trend Yearly",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "SE Type",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "SE Type",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Main Intent",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Main Intent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Foreign Intent",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Foreign Intent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Last Updated Time",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Last Updated Time",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Backlinks",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Backlinks",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Keyword Difficulty",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Keyword Difficulty",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "data",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "data",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "id",
"value": 129579803
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "1RERSXASXDADS"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4
},
{
"id": "1cd961c3-7823-4c00-b3a6-c99a98e68259",
"name": "Loop Over Domains",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-1280,
3680
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "30d02fea-f40b-442b-8f61-670d2f5931f2",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-1680,
3680
],
"parameters": {
"rule": {
"interval": [
{
"field": "months"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "407d3833-9585-48b8-855c-8389a23997be",
"name": "Get Keyword Difficulty",
"type": "n8n-nodes-base.httpRequest",
"maxTries": 2,
"position": [
-752,
3904
],
"parameters": {
"url": "https://api.dataforseo.com/v3/dataforseo_labs/google/bulk_keyword_difficulty/live",
"method": "POST",
"options": {},
"jsonBody": "={{ JSON.stringify([\n {\n \"keywords\": $json.tasks[0].result[0].items.map(i => i.keyword),\n \"location_name\": $('Loop Over Domains').item.json.location_name,\n \"language_name\": $('Loop Over Domains').item.json.language_name\n }\n]) }}",
"sendBody": true,
"specifyBody": "json"
},
"retryOnFail": true,
"typeVersion": 4.2,
"waitBetweenTries": 2000
},
{
"id": "21a50d5b-d650-49d0-88ba-e441b58a9f4d",
"name": "Get Keywords",
"type": "n8n-nodes-base.httpRequest",
"maxTries": 2,
"position": [
-1056,
3696
],
"parameters": {
"url": "https://api.dataforseo.com/v3/dataforseo_labs/google/keywords_for_site/live",
"method": "POST",
"options": {},
"jsonBody": "=[{\n \"target\": \"{{ $json.seed }}\",\n \"location_name\": \"{{ $json.location_name }}\",\n \"language_name\": \"{{ $json.language_name }}\",\n \"limit\": {{ $json.limit }}\n}]",
"sendBody": true,
"specifyBody": "json"
},
"retryOnFail": true,
"typeVersion": 4.2,
"waitBetweenTries": 2000
},
{
"id": "a6edc925-46cb-4511-9383-c7212665c339",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
-528,
3712
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition"
},
"typeVersion": 3.2
},
{
"id": "1dbfb339-bddc-48a5-b070-e8eeaa54f462",
"name": "Flatten Data",
"type": "n8n-nodes-base.code",
"position": [
112,
3712
],
"parameters": {
"jsCode": "const allRows = [];\n\nfor (const item of $input.all()) {\n if (item.json.data && Array.isArray(item.json.data)) {\n allRows.push(...item.json.data);\n }\n}\n\nreturn allRows.map(row => ({ json: row }));"
},
"typeVersion": 2
},
{
"id": "ec1a4714-ba6e-4345-a5c0-1b7fd12ee0c3",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1552,
3504
],
"parameters": {
"color": 7,
"content": "**Load Domain Seeds**\n\nReads domains from sheet and\nIncludes location, language, and limit parameters"
},
"typeVersion": 1
},
{
"id": "4f225165-8fe6-42c9-a45c-f5df3d75e19f",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1120,
3856
],
"parameters": {
"color": 7,
"content": "**Fetch Keywords**\n\nAPI: keywords_for_site\nReturns all keywords the domain ranks for\nLimited by \"limit\" parameter from sheet"
},
"typeVersion": 1
},
{
"id": "3227a544-aa1b-4aef-9ab6-f274d336dc58",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-816,
4064
],
"parameters": {
"color": 7,
"content": "**Get Difficulty Scores**\n\nAPI: bulk_keyword_difficulty\nChecks ranking difficulty (0-100) for all keywords\nRuns in parallel with keyword fetch"
},
"typeVersion": 1
},
{
"id": "56f921ba-01b4-4b7b-912f-c0a4641c1b97",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-560,
3568
],
"parameters": {
"color": 7,
"width": 320,
"height": 112,
"content": "**Combine & Format**\n\nMerges keyword data with difficulty scores\nFormats for Google Sheets output\nIncludes trends, intent, backlinks"
},
"typeVersion": 1
},
{
"id": "8ad8c2d6-585f-4bca-83da-3902e5433a22",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-96,
3568
],
"parameters": {
"color": 7,
"width": 368,
"height": 112,
"content": "**Aggregate Results**\n\nCollects all formatted rows\nFlattens nested data structure\nPrepares final dataset for writing"
},
"typeVersion": 1
}
],
"connections": {
"Merge": {
"main": [
[
{
"node": "Format Data",
"type": "main",
"index": 0
}
]
]
},
"Read Seeds": {
"main": [
[
{
"node": "Loop Over Domains",
"type": "main",
"index": 0
}
]
]
},
"Format Data": {
"main": [
[
{
"node": "Collect All Results",
"type": "main",
"index": 0
}
]
]
},
"Flatten Data": {
"main": [
[
{
"node": "Loop Over Domains",
"type": "main",
"index": 0
}
]
]
},
"Get Keywords": {
"main": [
[
{
"node": "Get Keyword Difficulty",
"type": "main",
"index": 0
},
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Read Seeds",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Domains": {
"main": [
[
{
"node": "Write to Sheet",
"type": "main",
"index": 0
}
],
[
{
"node": "Get Keywords",
"type": "main",
"index": 0
}
]
]
},
"Collect All Results": {
"main": [
[
{
"node": "Flatten Data",
"type": "main",
"index": 0
}
]
]
},
"Get Keyword Difficulty": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googleSheetsOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
What it does: Discovers all keywords a domain ranks for and analyzes their difficulty, trends, and intent. Identifies opportunities based on actual ranking data rather than suggestions.
Source: https://n8n.io/workflows/11216/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow automates video distribution to 9 social platforms simultaneously using Blotato's API. It includes both a scheduled publisher (checks Google Sheets for videos marked "Ready") and a subwo
YogiAI. Uses googleSheets, googleSheetsTool, httpRequest, stopAndError. Scheduled trigger; 61 nodes.
This workflow monitors Google Calendar for events indicating that a customer will visit the company today or the next day, retrieves the required details, and sends reminder notifications to the relev
ofn hook v0.24.0 beta. Uses start, httpRequest, functionItem, itemLists. Scheduled trigger; 42 nodes.
Security teams, DevOps engineers, vulnerability analysts, and automation builders who want to eliminate repetitive Nessus scan parsing, AI-based risk triage, and manual reporting. Designed for orgs fo