AutomationFlowsData & Sheets › Track AI Search Winners and Uncover Topic Gaps with Se Ranking and Google Sheets

Track AI Search Winners and Uncover Topic Gaps with Se Ranking and Google Sheets

ByEugene Melnychenko @eugene-m on n8n.io

SEO teams comparing AI search visibility against competitors Content strategists planning editorial calendars around AI search gaps Marketing managers reporting share of voice across ChatGPT, Perplexity, and Gemini

Event trigger★★★★★ complexity31 nodesForm Trigger@Seranking/N8N Nodes SerankingGoogle Sheets
Data & Sheets Trigger: Event Nodes: 31 Complexity: ★★★★★ Added:

This workflow corresponds to n8n.io template #14257 — we link there as the canonical source.

This workflow follows the Form Trigger → Google Sheets 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 →

Download .json
{
  "name": "Track who wins AI search and find the topics you're missing with SE Ranking",
  "tags": [],
  "nodes": [
    {
      "id": "5cfd1015-76d4-4a32-bac2-92f9306865e5",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3584,
        1664
      ],
      "parameters": {
        "color": 5,
        "width": 568,
        "height": 1448,
        "content": "## Track who wins AI search and find the topics you're missing with SE Ranking\n\n## Who is this for\n- SEO teams comparing AI search visibility against competitors\n- Content strategists planning editorial calendars around AI search gaps\n- Marketing managers reporting share of voice across ChatGPT, Perplexity, and Gemini\n\n## What this workflow does\nSee who's winning AI search across all major LLMs, then find the organic keyword gaps and unanswered questions your competitors are capturing that you're not \u2014 and save everything to Google Sheets.\n\n## What you'll get\n- AI search leaderboard with share of voice across ChatGPT, Perplexity, Gemini, AI Overviews, and AI Mode\n- Organic keyword gaps where competitors rank but you don't, sorted by volume\n- Question keywords your audience asks around your seed topic \u2014 ready to write against\n- Prompts where you already appear in AI search results\n- SEO topics where your competitor shows up in AI answers but you don't\n\n## How it works\n1. Add your domain and 2 competitors in the form \u2014 it looks up the AI search leaderboard across all 5 LLM engines and shows who's winning\n2. Pulls organic keyword gaps against both competitors sorted by volume, filtered for English keywords\n3. Finds question keywords your audience asks around your seed topic, filtered by informational intent\n4. Gets the top prompts where you already show up in AI search results\n5. Pulls your competitors' top SEO prompts and compares against your footprint to find where they appear but you don't\n6. Saves all five data sets to separate tabs in Google Sheets\n\n## Requirements\n- SE Ranking community node installed\n- SE Ranking API token ([Get one here](https://online.seranking.com/admin.api.dashboard.html))\n- Google Sheets account (optional)\n\n## Setup\n1. Install the [SE Ranking community node](https://www.npmjs.com/package/@seranking/n8n-nodes-seranking)\n2. Add your SE Ranking API credentials\n3. Connect your Google Sheets account and set a spreadsheet URL in each export node\n4. Activate the workflow \u2014 n8n generates a unique form URL you can share or embed\n5. Open the form, fill in your domain and competitors, and the workflow runs automatically\n\n## Customization\n- Change `volume_min` in the Configuration node to raise or lower the keyword volume threshold\n- Change `source` in the Configuration node for a different regional database (us, uk, de, fr, es, etc.)\n- Swap `seed_topic` in Configuration to any keyword your business targets to get a fresh set of questions"
      },
      "typeVersion": 1
    },
    {
      "id": "e773dbac-6dbe-45a0-a015-6b4c05f56aae",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4064,
        3248
      ],
      "parameters": {
        "color": 7,
        "width": 456,
        "height": 464,
        "content": "### \ud83d\udccb How to share or embed this form\n\n1. **Activate** the workflow using the toggle in the top right\n2. Open the **Domain Input Form** node and copy the **Production URL**\n3. **Share the link** directly \u2014 anyone with the URL can fill in their domain and trigger the workflow\n4. **Embed on your website** using an iframe:\n\n```html\n<iframe\n  src=\"YOUR_PRODUCTION_URL\"\n  width=\"600\"\n  height=\"500\"\n  frameborder=\"0\">\n</iframe>\n```\n\nEach form submission runs the full workflow automatically."
      },
      "typeVersion": 1
    },
    {
      "id": "eba74508-75d0-465a-af5c-637533f30207",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4624,
        1984
      ],
      "parameters": {
        "color": 7,
        "width": 868,
        "height": 334,
        "content": "### \ud83c\udfc6 AI Search Leaderboard\nCompares you and up to 2 competitors across ChatGPT, Perplexity, Gemini, AI Overviews, and AI Mode \u2014 returns share of voice and presence scores per engine."
      },
      "typeVersion": 1
    },
    {
      "id": "0891b8ae-04c0-4672-ad30-03a8e303f474",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4784,
        3040
      ],
      "parameters": {
        "color": 7,
        "width": 1172,
        "height": 846,
        "content": "### \ud83e\udd16 AI Footprint Comparison\nYour AI topics and both competitors' topics merge before the gap code runs. \nOnly SEO-context prompts are kept \u2014 filters out unrelated brand mentions."
      },
      "typeVersion": 1
    },
    {
      "id": "836d8671-7dbd-495e-acb0-03fce1988827",
      "name": "Domain Input Form",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        4320,
        3008
      ],
      "parameters": {
        "options": {},
        "formTitle": "AI Search Gap Analysis",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Your Domain",
              "placeholder": "example.com",
              "requiredField": true
            },
            {
              "fieldLabel": "Your Brand Name",
              "placeholder": "Example",
              "requiredField": true
            },
            {
              "fieldLabel": "Seed Topic",
              "placeholder": "seo software",
              "requiredField": true
            },
            {
              "fieldLabel": "Competitor 1 Domain",
              "placeholder": "competitor1.com",
              "requiredField": true
            },
            {
              "fieldLabel": "Competitor 1 Brand",
              "placeholder": "Competitor One",
              "requiredField": true
            },
            {
              "fieldLabel": "Competitor 2 Domain",
              "placeholder": "competitor2.com"
            },
            {
              "fieldLabel": "Competitor 2 Brand",
              "placeholder": "Competitor Two"
            },
            {
              "fieldType": "dropdown",
              "fieldLabel": "Target Market",
              "fieldOptions": {
                "values": [
                  {
                    "option": "us"
                  },
                  {
                    "option": "uk"
                  },
                  {
                    "option": "de"
                  },
                  {
                    "option": "fr"
                  },
                  {
                    "option": "es"
                  },
                  {
                    "option": "it"
                  },
                  {
                    "option": "au"
                  },
                  {
                    "option": "ca"
                  },
                  {
                    "option": "pl"
                  }
                ]
              },
              "requiredField": true
            }
          ]
        },
        "formDescription": "Enter your domain and up to 2 competitors to see who's winning AI search and find the topics you're missing."
      },
      "typeVersion": 2.2
    },
    {
      "id": "940ff7c6-93f6-48d1-a834-ec408d770e93",
      "name": "Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        4512,
        3008
      ],
      "parameters": {
        "fields": {
          "values": [
            {
              "name": "your_domain",
              "stringValue": "={{ $json['Your Domain'] }}"
            },
            {
              "name": "your_brand",
              "stringValue": "={{ $json['Your Brand Name'] }}"
            },
            {
              "name": "competitor_domain_1",
              "stringValue": "={{ $json['Competitor 1 Domain'] }}"
            },
            {
              "name": "competitor_brand_1",
              "stringValue": "={{ $json['Competitor 1 Brand'] }}"
            },
            {
              "name": "competitor_domain_2",
              "stringValue": "={{ $json['Competitor 2 Domain'] || $json['Competitor 1 Domain'] }}"
            },
            {
              "name": "competitor_brand_2",
              "stringValue": "={{ $json['Competitor 2 Brand'] || $json['Competitor 1 Brand'] }}"
            },
            {
              "name": "seed_topic",
              "stringValue": "={{ $json['Seed Topic'] }}"
            },
            {
              "name": "source",
              "stringValue": "={{ $json['Target Market'] }}"
            },
            {
              "name": "scope",
              "stringValue": "base_domain"
            },
            {
              "name": "volume_min",
              "stringValue": "500"
            },
            {
              "name": "results_limit",
              "stringValue": "200"
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "0d58b9d5-49ae-4c1d-bf78-d549014949f9",
      "name": "Get AI leaderboard",
      "type": "@seranking/n8n-nodes-seranking.seRanking",
      "position": [
        4800,
        2144
      ],
      "parameters": {
        "source": "={{ $json.source }}",
        "engines": [
          "ai-overview",
          "chatgpt",
          "perplexity",
          "gemini"
        ],
        "resource": "aiSearch",
        "operation": "getLeaderboard",
        "competitors": {
          "competitorValues": [
            {
              "brand": "={{ $json.competitor_brand_1 }}",
              "target": "={{ $json.competitor_domain_1 }}"
            },
            {
              "brand": "={{ $json.competitor_brand_2 }}",
              "target": "={{ $json.competitor_domain_2 }}"
            }
          ]
        },
        "primaryBrand": "={{ $json.your_brand }}",
        "primaryTarget": "={{ $json.your_domain }}"
      },
      "credentials": {
        "seRankingApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "6834e6f3-56a0-434e-bddc-9e078dc54650",
      "name": "Format leaderboard",
      "type": "n8n-nodes-base.code",
      "position": [
        5008,
        2144
      ],
      "parameters": {
        "jsCode": "const data = $input.first().json;\nconst leaderboard = data.leaderboard || [];\nconst results = data.results || {};\n\nreturn leaderboard.map(item => ({\n  json: {\n    rank: item.rank,\n    domain: item.domain,\n    share_of_voice_pct: ((item.share_of_voice || 0) * 100).toFixed(1) + '%',\n    brand_presence_total: item.brand_presence || 0,\n    link_presence_total: item.link_presence || 0,\n    is_your_domain: item.is_primary_target ? 'Yes' : 'No',\n    chatgpt_brand: results[item.domain]?.chatgpt?.brand_presence || 0,\n    chatgpt_links: results[item.domain]?.chatgpt?.link_presence || 0,\n    perplexity_brand: results[item.domain]?.perplexity?.brand_presence || 0,\n    perplexity_links: results[item.domain]?.perplexity?.link_presence || 0,\n    gemini_brand: results[item.domain]?.gemini?.brand_presence || 0,\n    gemini_links: results[item.domain]?.gemini?.link_presence || 0,\n    ai_overview_brand: results[item.domain]?.['ai-overview']?.brand_presence || 0,\n    ai_overview_links: results[item.domain]?.['ai-overview']?.link_presence || 0,\n    ai_mode_brand: results[item.domain]?.['ai-mode']?.brand_presence || 0,\n    ai_mode_links: results[item.domain]?.['ai-mode']?.link_presence || 0,\n    date: new Date().toISOString().split('T')[0]\n  }\n}));"
      },
      "typeVersion": 2
    },
    {
      "id": "c352e9d6-50f6-4ab7-b186-99bb85d1e73a",
      "name": "Export to Sheets: AI Leaderboard",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        5312,
        2144
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "6ba86cc5-4111-4646-abca-3c0e13dc5b0c",
      "name": "Wait before keyword gap (3s)",
      "type": "n8n-nodes-base.wait",
      "position": [
        4816,
        2512
      ],
      "parameters": {
        "amount": 3
      },
      "typeVersion": 1.1
    },
    {
      "id": "105ca5bf-d3a5-4c64-a5c1-dda76f1317d7",
      "name": "Get keyword gaps 1st Competitor",
      "type": "@seranking/n8n-nodes-seranking.seRanking",
      "position": [
        5152,
        2432
      ],
      "parameters": {
        "diff": "1",
        "domain": "={{ $('Configuration').item.json.competitor_domain_1 }}",
        "source": "={{ $('Configuration').item.json.source }}",
        "operation": "getKeywordsComparison",
        "compareDomain": "={{ $('Configuration').item.json.your_domain }}",
        "additionalFields": {
          "limit": "={{ $('Configuration').item.json.results_limit }}",
          "orderType": "desc",
          "orderField": "volume"
        }
      },
      "credentials": {
        "seRankingApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d8388977-87a7-4de9-aae4-065cd9c4ee1a",
      "name": "Wait before keyword gap (3s)1",
      "type": "n8n-nodes-base.wait",
      "position": [
        5040,
        2608
      ],
      "parameters": {
        "amount": 3
      },
      "typeVersion": 1.1
    },
    {
      "id": "e7697519-dddb-4e40-8042-6283a72f4779",
      "name": "Get keyword gaps 2nd Competitor",
      "type": "@seranking/n8n-nodes-seranking.seRanking",
      "position": [
        5264,
        2608
      ],
      "parameters": {
        "diff": "1",
        "domain": "={{ $('Configuration').item.json.competitor_domain_2 }}",
        "source": "={{ $('Configuration').item.json.source }}",
        "operation": "getKeywordsComparison",
        "compareDomain": "={{ $('Configuration').item.json.your_domain }}",
        "additionalFields": {
          "limit": "={{ $('Configuration').item.json.results_limit }}",
          "orderType": "desc",
          "orderField": "volume"
        }
      },
      "credentials": {
        "seRankingApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "39606454-3fb5-4cc3-88e1-08da7c2e9ae4",
      "name": "Merge keyword gaps",
      "type": "n8n-nodes-base.merge",
      "position": [
        5488,
        2512
      ],
      "parameters": {},
      "typeVersion": 2.1
    },
    {
      "id": "79404595-eb60-4ce8-bd03-d371fb290962",
      "name": "Format keyword gaps",
      "type": "n8n-nodes-base.code",
      "position": [
        5712,
        2512
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nconst config = $('Configuration').first().json;\nconst volumeMin = parseInt(config.volume_min) || 500;\n\n// Keep only Latin/English keywords \u2014 filters out Asian and non-Latin scripts\nconst isLatin = kw => /^[a-zA-Z0-9\\s\\-_'\".,?!&%()/\\\\+:;]+$/.test(kw.trim());\n\n// Deduplicate across both competitor calls\nconst seen = new Set();\n\nreturn items\n  .filter(item => {\n    const kw = item.json.keyword || '';\n    return kw && isLatin(kw) && (item.json.volume || 0) >= volumeMin;\n  })\n  .filter(item => {\n    const key = item.json.keyword.toLowerCase().trim();\n    if (seen.has(key)) return false;\n    seen.add(key);\n    return true;\n  })\n  .map(item => ({\n    json: {\n      keyword: item.json.keyword,\n      volume: item.json.volume || 0,\n      difficulty: item.json.difficulty || 0,\n      cpc: item.json.cpc || 0,\n      competitor_position: item.json.position || '\u2014',\n      competitor_url: item.json.url || '',\n      your_position: item.json.compare_position || '\u2014',\n      your_domain: config.your_domain,\n      date: new Date().toISOString().split('T')[0]\n    }\n  }))\n  .slice(0, 40);"
      },
      "typeVersion": 2
    },
    {
      "id": "4dfa9aaf-62d9-47c9-afed-1b82aa5ee16e",
      "name": "Export to Sheets: Organic Gaps",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        5936,
        2512
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "c8cdd7bb-c1de-4567-8c99-6f5de6991d3b",
      "name": "Wait before questions (6s)",
      "type": "n8n-nodes-base.wait",
      "position": [
        4896,
        2800
      ],
      "parameters": {
        "amount": 6
      },
      "typeVersion": 1.1
    },
    {
      "id": "12019e1e-6ba7-4f8a-b8e1-8b5936bff850",
      "name": "Get question keywords",
      "type": "@seranking/n8n-nodes-seranking.seRanking",
      "position": [
        5104,
        2800
      ],
      "parameters": {
        "source": "={{ $('Configuration').item.json.source }}",
        "keyword": "={{ $('Configuration').item.json.seed_topic }}",
        "resource": "keywordResearch",
        "operation": "getQuestions",
        "additionalFields": {
          "limit": 30,
          "intents": [
            "I"
          ],
          "volumeFrom": "={{ $('Configuration').item.json.volume_min }}"
        }
      },
      "credentials": {
        "seRankingApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "85853350-254c-44f3-a738-dff0c52151eb",
      "name": "Format questions",
      "type": "n8n-nodes-base.code",
      "position": [
        5360,
        2800
      ],
      "parameters": {
        "jsCode": "const data = $input.first().json;\nconst keywords = data.keywords || [];\nconst config = $('Configuration').first().json;\n\nreturn keywords\n  .filter(kw => kw.keyword)\n  .map(kw => ({\n    json: {\n      question: kw.keyword,\n      volume: kw.volume || 0,\n      difficulty: kw.difficulty || 0,\n      cpc: kw.cpc || 0,\n      serp_features: (kw.serp_features || []).join(', '),\n      intent: (kw.intents || []).join(', '),\n      seed_topic: config.seed_topic,\n      date: new Date().toISOString().split('T')[0]\n    }\n  }))\n  .slice(0, 30);"
      },
      "typeVersion": 2
    },
    {
      "id": "231c7a4e-a48c-4e55-85b0-1e3694529099",
      "name": "Export to Sheets: Questions",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        5616,
        2800
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "9a74573c-6cef-4859-94e2-f3415fafcb8b",
      "name": "Wait before your AI topics (9s)",
      "type": "n8n-nodes-base.wait",
      "position": [
        4832,
        3184
      ],
      "parameters": {
        "amount": 9
      },
      "typeVersion": 1.1
    },
    {
      "id": "9d2150b2-7d44-4e7d-b281-efb77f3489c6",
      "name": "Get your AI topics",
      "type": "@seranking/n8n-nodes-seranking.seRanking",
      "position": [
        5040,
        3184
      ],
      "parameters": {
        "scope": "={{ $('Configuration').item.json.scope }}",
        "domain": "={{ $('Configuration').item.json.your_domain }}",
        "engine": "ai-overview",
        "source": "={{ $('Configuration').item.json.source }}",
        "resource": "aiSearch",
        "operation": "getPromptsByTarget",
        "additionalFields": {
          "sort": "volume",
          "limit": "={{ $('Configuration').item.json.results_limit }}",
          "sortOrder": "desc",
          "volumeFrom": 500
        }
      },
      "credentials": {
        "seRankingApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "aeb0a034-82a2-46b3-9f36-e31b3e14bfc4",
      "name": "Format your AI topics",
      "type": "n8n-nodes-base.code",
      "position": [
        5264,
        3184
      ],
      "parameters": {
        "jsCode": "const data = $input.first().json;\nconst prompts = data.prompts || [];\nconst config = $('Configuration').first().json;\n\nreturn prompts.map(p => ({\n  json: {\n    prompt: p.prompt || '',\n    volume: p.volume || 0,\n    appearance_type: p.type || '',\n    snippet_preview: (() => { try { return (p.answer?.text || '').substring(0, 200); } catch(e) { return ''; } })(),\n    your_domain: config.your_domain,\n    date: new Date().toISOString().split('T')[0]\n  }\n}));"
      },
      "typeVersion": 2
    },
    {
      "id": "3bf02165-88d5-4121-8e62-28dbfc0aabd0",
      "name": "Export to Sheets: Your AI Topics",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        5552,
        3184
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "84c52904-e14f-4105-ae10-4ae655e48180",
      "name": "Wait before competitor topics (12s)",
      "type": "n8n-nodes-base.wait",
      "position": [
        4832,
        3424
      ],
      "parameters": {
        "amount": 12
      },
      "typeVersion": 1.1
    },
    {
      "id": "539fe1f1-1fc3-4701-bb92-42e9cfb94132",
      "name": "Wait before competitor topics (10s)",
      "type": "n8n-nodes-base.wait",
      "position": [
        4832,
        3648
      ],
      "parameters": {
        "amount": 12
      },
      "typeVersion": 1.1
    },
    {
      "id": "b30db186-858a-4b0f-b1e6-1aa01383f398",
      "name": "Get 1st competitor AI topics",
      "type": "@seranking/n8n-nodes-seranking.seRanking",
      "position": [
        5040,
        3424
      ],
      "parameters": {
        "engine": "ai-overview",
        "source": "={{ $('Configuration').item.json.source }}",
        "resource": "aiSearch",
        "brandName": "={{ $('Configuration').item.json.competitor_brand_1 }}",
        "operation": "getPromptsByBrand",
        "additionalFields": {
          "sort": "volume",
          "limit": "={{ $('Configuration').item.json.results_limit }}",
          "sortOrder": "desc",
          "volumeFrom": "={{ $('Configuration').item.json.volume_min }}",
          "multiKeywordIncluded": "seo"
        }
      },
      "credentials": {
        "seRankingApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ccc3cd38-819e-4d0b-91c1-5058a12bba6f",
      "name": "Get 2nd competitor AI topics",
      "type": "@seranking/n8n-nodes-seranking.seRanking",
      "position": [
        5040,
        3648
      ],
      "parameters": {
        "engine": "ai-overview",
        "source": "={{ $('Configuration').item.json.source }}",
        "resource": "aiSearch",
        "brandName": "={{ $('Configuration').item.json.competitor_brand_2 }}",
        "operation": "getPromptsByBrand",
        "additionalFields": {
          "sort": "volume",
          "limit": "={{ $('Configuration').item.json.results_limit }}",
          "sortOrder": "desc",
          "volumeFrom": "={{ $('Configuration').item.json.volume_min }}",
          "multiKeywordIncluded": "seo"
        }
      },
      "credentials": {
        "seRankingApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f60eea69-4efc-4665-875c-a9fe91dbb137",
      "name": "Merge your topics and competitor topics",
      "type": "n8n-nodes-base.merge",
      "position": [
        5376,
        3408
      ],
      "parameters": {
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "cc5119e1-7b50-48c9-be7a-0e1a54b16fff",
      "name": "Find topics you're missing",
      "type": "n8n-nodes-base.code",
      "position": [
        5568,
        3424
      ],
      "parameters": {
        "jsCode": "const allInputs = $input.all();\nconst config = $('Configuration').first().json;\n\n// SEO context filter \u2014 keeps only prompts related to SEO topics\nconst seoTerms = ['seo', 'keyword', 'ranking', 'backlink', 'serp', 'traffic',\n  'search engine', 'rank track', 'domain', 'audit', 'content', 'google', 'organic',\n  'link building', 'on-page', 'off-page', 'site speed', 'crawl', 'index'];\nconst isSeoRelated = prompt =>\n  seoTerms.some(t => (prompt || '').toLowerCase().includes(t));\n\n// Your topics: formatted rows \u2014 each has your_domain field\nconst yourItems = allInputs.filter(i => i.json.your_domain !== undefined);\nconst yourPrompts = new Set(\n  yourItems.map(i => (i.json.prompt || '').toLowerCase().trim())\n);\n\n// Competitor data: raw API responses \u2014 items with prompts array\n// Tag each prompt with its source competitor brand before flattening\nconst competitorItems = allInputs.filter(i => i.json.prompts !== undefined);\nconst competitorPrompts = competitorItems.flatMap((item, idx) => {\n  const brand = idx === 0 ? config.competitor_brand_1 : config.competitor_brand_2;\n  return (item.json.prompts || []).map(p => ({ ...p, _competitor: brand }));\n});\n\nconst seen = new Set();\n\nconst gaps = competitorPrompts\n  .filter(p => {\n    const normalised = (p.prompt || '').toLowerCase().trim();\n    if (!normalised || yourPrompts.has(normalised) || !isSeoRelated(p.prompt)) return false;\n    if (seen.has(normalised)) return false;\n    seen.add(normalised);\n    return true;\n  })\n  .map(p => ({\n    json: {\n      prompt: p.prompt || '',\n      volume: p.volume || 0,\n      their_appearance_type: p.type || '',\n      snippet_preview: (() => { try { return (p.answer?.text || '').substring(0, 200); } catch(e) { return ''; } })(),\n      competitor: p._competitor,\n      gap_note: 'Competitor appears here \u2014 you do not',\n      date: new Date().toISOString().split('T')[0]\n    }\n  }));\n\nreturn gaps.slice(0, 300);"
      },
      "typeVersion": 2
    },
    {
      "id": "95f4fa5a-0e17-4f3b-b5c0-87f9d4196dfe",
      "name": "Export to Sheets: Competitor AI Topics",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        5776,
        3424
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": ""
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Configuration": {
      "main": [
        [
          {
            "node": "Get AI leaderboard",
            "type": "main",
            "index": 0
          },
          {
            "node": "Wait before keyword gap (3s)",
            "type": "main",
            "index": 0
          },
          {
            "node": "Wait before questions (6s)",
            "type": "main",
            "index": 0
          },
          {
            "node": "Wait before your AI topics (9s)",
            "type": "main",
            "index": 0
          },
          {
            "node": "Wait before competitor topics (12s)",
            "type": "main",
            "index": 0
          },
          {
            "node": "Wait before competitor topics (10s)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format questions": {
      "main": [
        [
          {
            "node": "Export to Sheets: Questions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Domain Input Form": {
      "main": [
        [
          {
            "node": "Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format leaderboard": {
      "main": [
        [
          {
            "node": "Export to Sheets: AI Leaderboard",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get AI leaderboard": {
      "main": [
        [
          {
            "node": "Format leaderboard",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get your AI topics": {
      "main": [
        [
          {
            "node": "Format your AI topics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge keyword gaps": {
      "main": [
        [
          {
            "node": "Format keyword gaps",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format keyword gaps": {
      "main": [
        [
          {
            "node": "Export to Sheets: Organic Gaps",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format your AI topics": {
      "main": [
        [
          {
            "node": "Export to Sheets: Your AI Topics",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge your topics and competitor topics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get question keywords": {
      "main": [
        [
          {
            "node": "Format questions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find topics you're missing": {
      "main": [
        [
          {
            "node": "Export to Sheets: Competitor AI Topics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait before questions (6s)": {
      "main": [
        [
          {
            "node": "Get question keywords",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get 1st competitor AI topics": {
      "main": [
        [
          {
            "node": "Merge your topics and competitor topics",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Get 2nd competitor AI topics": {
      "main": [
        [
          {
            "node": "Merge your topics and competitor topics",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Wait before keyword gap (3s)": {
      "main": [
        [
          {
            "node": "Get keyword gaps 1st Competitor",
            "type": "main",
            "index": 0
          },
          {
            "node": "Wait before keyword gap (3s)1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait before keyword gap (3s)1": {
      "main": [
        [
          {
            "node": "Get keyword gaps 2nd Competitor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get keyword gaps 1st Competitor": {
      "main": [
        [
          {
            "node": "Merge keyword gaps",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get keyword gaps 2nd Competitor": {
      "main": [
        [
          {
            "node": "Merge keyword gaps",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Wait before your AI topics (9s)": {
      "main": [
        [
          {
            "node": "Get your AI topics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait before competitor topics (10s)": {
      "main": [
        [
          {
            "node": "Get 2nd competitor AI topics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait before competitor topics (12s)": {
      "main": [
        [
          {
            "node": "Get 1st competitor AI topics",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge your topics and competitor topics": {
      "main": [
        [
          {
            "node": "Find topics you're missing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

SEO teams comparing AI search visibility against competitors Content strategists planning editorial calendars around AI search gaps Marketing managers reporting share of voice across ChatGPT, Perplexity, and Gemini

Source: https://n8n.io/workflows/14257/ — original creator credit. Request a take-down →

More Data & Sheets workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Data & Sheets

Ultimate Extract by RoboNuggets (R46). Uses @apify/n8n-nodes-apify, googleSheets, formTrigger. Event-driven trigger; 42 nodes.

@Apify/N8N Nodes Apify, Google Sheets, Form Trigger
Data & Sheets

Overview 🌐

Form Trigger, HTTP Request, Google Sheets
Data & Sheets

Splitout Code. Uses splitOut, httpRequest, googleSheets, stickyNote. Event-driven trigger; 36 nodes.

HTTP Request, Google Sheets, Form Trigger +1
Data & Sheets

This n8n workflow is designed for Customer Success Managers (CSM), marketers, sales teams, and data administrators who need to automate the process of uploading and processing CSV data in HubSpot. It

HTTP Request, Google Sheets, Form Trigger +1
Data & Sheets

Marketing teams tracking AI SEO performance Content strategists planning editorial calendars SEO teams doing competitive intelligence

@Seranking/N8N Nodes Seranking, Google Sheets