AutomationFlowsAI & RAG › Generate SEO Content Briefs From Keywords with Serpapi, Openai, Google Docs…

Generate SEO Content Briefs From Keywords with Serpapi, Openai, Google Docs…

Original n8n title: Generate SEO Content Briefs From Keywords with Serpapi, Openai, Google Docs and Sheets

ByTakatoYamada @takato-door on n8n.io

This workflow collects a keyword via an n8n form, pulls the top Google results using SerpApi, scrapes headings from competitor pages, and uses OpenAI to generate a structured SEO content brief, which it saves to Google Docs and logs to Google Sheets. Receives a keyword, target…

Event trigger★★★★☆ complexityAI-powered23 nodesForm TriggerHTTP RequestChain LlmOpenAI ChatOutput Parser StructuredGoogle DocsGoogle Sheets
AI & RAG Trigger: Event Nodes: 23 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Chainllm → Form Trigger 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
{
  "id": "1e410644246ed3ca",
  "name": "Generate an SEO content brief from a keyword with SERP analysis and OpenAI",
  "tags": [
    {
      "name": "seo"
    },
    {
      "name": "content-brief"
    },
    {
      "name": "serp"
    },
    {
      "name": "content-marketing"
    },
    {
      "name": "web-scraping"
    },
    {
      "name": "google-docs"
    },
    {
      "name": "openai"
    },
    {
      "name": "ai"
    }
  ],
  "nodes": [
    {
      "id": "6cebe2a0-4c04-48f2-831a-3a556b697bd0",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -640,
        -176
      ],
      "parameters": {
        "width": 480,
        "height": 720,
        "content": "## Generate an SEO content brief from a keyword with SERP analysis and OpenAI\n\n## How it works\n\n1. Receives a keyword input via a form trigger.\n2. Queries the Google SERP API for search results.\n3. Extracts and limits to top 10 competitor pages.\n4. Fetches and analyzes competitor content to build a brief.\n5. Formats and logs the SEO content brief into documents and sheets.\n\n## Setup steps\n\n- [ ] Set up SERP API credentials for querying Google search results.\n- [ ] Configure OpenAI API credentials for generating the content brief.\n- [ ] Authenticate Google Docs and Sheets access for document creation.\n\n## Customization\n\nConsider adjusting the output format in Google Docs or Sheets as per your specific requirements."
      },
      "typeVersion": 1
    },
    {
      "id": "26844be8-5609-49f4-a873-b35a26afa201",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        -128
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 304,
        "content": "## Trigger and search query\n\nInitiates the process with a keyword and queries the SERP API."
      },
      "typeVersion": 1
    },
    {
      "id": "fa897edc-4daf-4c5b-bb0f-cde1ab472c0a",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        400,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 272,
        "content": "## Process SERP results\n\nExtracts and processes top organic results."
      },
      "typeVersion": 1
    },
    {
      "id": "4c4048b1-baa4-4fa1-bdd4-e75ecd38f8f5",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        832,
        -112
      ],
      "parameters": {
        "color": 7,
        "width": 592,
        "height": 272,
        "content": "## Fetch and analyze competitors\n\nFetches competitor pages and extracts heading and text content."
      },
      "typeVersion": 1
    },
    {
      "id": "cdc794a6-6690-464f-9cf7-f4fe491a3d10",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1456,
        -176
      ],
      "parameters": {
        "color": 7,
        "width": 656,
        "height": 512,
        "content": "## Generate content brief\n\nAnalyzes data and builds an SEO content brief using AI."
      },
      "typeVersion": 1
    },
    {
      "id": "db4cd001-971e-4b8f-b03a-00abd23dfe10",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2144,
        -176
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 272,
        "content": "## Document management\n\nCreates and logs the SEO content brief in Google Docs and Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "77500abb-7341-4d5e-9a72-2628ad5074f0",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1184,
        192
      ],
      "parameters": {
        "color": 7,
        "width": 240,
        "height": 352,
        "content": "## Handle insufficient data\n\nManages workflow when not enough SERP data is available."
      },
      "typeVersion": 1
    },
    {
      "id": "6221d4e5-1ba2-4eb1-b96c-efc7e183af85",
      "name": "When Form Submitted",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -40,
        0
      ],
      "parameters": {
        "options": {},
        "formTitle": "SEO Content Brief Generator",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Keyword",
              "placeholder": "e.g. best crm for small business",
              "requiredField": true
            },
            {
              "fieldType": "dropdown",
              "fieldLabel": "Target country",
              "fieldOptions": {
                "values": [
                  {
                    "option": "us"
                  },
                  {
                    "option": "uk"
                  },
                  {
                    "option": "jp"
                  },
                  {
                    "option": "de"
                  },
                  {
                    "option": "au"
                  }
                ]
              },
              "requiredField": true
            },
            {
              "fieldType": "dropdown",
              "fieldLabel": "Search intent",
              "fieldOptions": {
                "values": [
                  {
                    "option": "informational"
                  },
                  {
                    "option": "commercial"
                  },
                  {
                    "option": "transactional"
                  }
                ]
              }
            }
          ]
        },
        "formDescription": "Enter a target keyword to get a data-driven content brief built from the current top-ranking pages."
      },
      "typeVersion": 2.2
    },
    {
      "id": "bd976c29-5922-45cd-9f52-41f2369f87cc",
      "name": "Fetch SERP Results",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        200,
        0
      ],
      "parameters": {
        "url": "https://serpapi.com/search.json",
        "options": {
          "response": {
            "response": {
              "neverError": true
            }
          }
        },
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpQueryAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "engine",
              "value": "google"
            },
            {
              "name": "q",
              "value": "={{ $json.Keyword }}"
            },
            {
              "name": "gl",
              "value": "={{ $json['Target country'] }}"
            },
            {
              "name": "num",
              "value": "10"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "e237948f-72a4-46b4-a9d4-e36da3cc42be",
      "name": "Split Organic Search Results",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        448,
        0
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "organic_results"
      },
      "typeVersion": 1
    },
    {
      "id": "e98d48ba-d5f4-4c02-abda-9d923ea4eaf2",
      "name": "Limit to Top 10 Competitors",
      "type": "n8n-nodes-base.limit",
      "position": [
        656,
        0
      ],
      "parameters": {
        "maxItems": 10
      },
      "typeVersion": 1
    },
    {
      "id": "5b8b452c-5ef1-43df-81b2-e86f259cec55",
      "name": "Fetch Competitor Sites",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        880,
        0
      ],
      "parameters": {
        "url": "={{ $json.link }}",
        "options": {
          "response": {
            "response": {
              "neverError": true
            }
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "7942033a-6f35-4036-8abc-f15285a53225",
      "name": "Extract Page Headings",
      "type": "n8n-nodes-base.html",
      "position": [
        1088,
        0
      ],
      "parameters": {
        "options": {},
        "operation": "extractHtmlContent",
        "dataPropertyName": "data",
        "extractionValues": {
          "values": [
            {
              "key": "page_title",
              "cssSelector": "title"
            },
            {
              "key": "h1",
              "cssSelector": "h1",
              "returnArray": true
            },
            {
              "key": "headings",
              "cssSelector": "h2, h3",
              "returnArray": true
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "4b54086e-04c1-40b7-aa4d-5b843d968f79",
      "name": "Aggregate Competitor Signals",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        1280,
        0
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "49f61f25-530c-45ac-bd73-ba3a839e71df",
      "name": "Check SERP Data Sufficiency",
      "type": "n8n-nodes-base.if",
      "position": [
        1504,
        0
      ],
      "parameters": {
        "conditions": {
          "options": {
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.data.length }}",
              "rightValue": 3
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "55ca7113-8d43-4b6b-b353-0cb5cff5803d",
      "name": "Generate SEO Content Brief",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        1744,
        -64
      ],
      "parameters": {
        "text": "=You are an expert SEO content strategist. Produce a content brief designed to OUTRANK the current top-ranking pages for the target keyword.\n\nTarget keyword: {{ $('When Form Submitted').item.json.Keyword }}\nMarket (gl): {{ $('When Form Submitted').item.json['Target country'] }}\nSearch intent: {{ $('When Form Submitted').item.json['Search intent'] }}\n\nCompetitor pages currently ranking (titles + H1/H2/H3 headings scraped live):\n{{ JSON.stringify($json.data).slice(0, 6000) }}\n\nAnalyse the competitors' structure and topical coverage, then return a brief that is more complete and better targeted. Cover gaps the competitors miss. Recommend a realistic word count based on the competitor average.",
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.5
    },
    {
      "id": "d01e900f-9d09-4ade-a76b-f3d66d1e6b95",
      "name": "OpenAI Brief Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1744,
        208
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o",
          "cachedResultName": "gpt-4o"
        },
        "options": {
          "temperature": 0.4
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "aabd21c3-ee23-4ef4-abca-1a94f2277d5d",
      "name": "Output Parser Schema",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1968,
        208
      ],
      "parameters": {
        "schemaType": "fromJson",
        "jsonSchemaExample": "{\n  \"primary_keyword\": \"best crm for small business\",\n  \"search_intent\": \"commercial\",\n  \"title_options\": [\n    \"Best CRM for Small Business in 2026: Top 9 Compared\",\n    \"The 9 Best Small Business CRMs (Tested & Ranked)\"\n  ],\n  \"meta_description\": \"Compare the 9 best CRMs for small businesses in 2026 on price, ease of use and automation \u2014 with a pick for every budget.\",\n  \"target_word_count\": 2200,\n  \"recommended_outline\": [\n    {\n      \"h2\": \"What to look for in a small business CRM\",\n      \"h3\": [\n        \"Ease of use\",\n        \"Pricing\",\n        \"Automation\"\n      ]\n    },\n    {\n      \"h2\": \"The 9 best CRMs compared\",\n      \"h3\": [\n        \"HubSpot\",\n        \"Pipedrive\",\n        \"Zoho\"\n      ]\n    }\n  ],\n  \"secondary_keywords\": [\n    \"affordable crm\",\n    \"crm with automation\",\n    \"easy crm for startups\"\n  ],\n  \"people_also_ask\": [\n    \"What is the cheapest CRM for a small business?\",\n    \"Do small businesses need a CRM?\"\n  ],\n  \"content_gaps\": [\n    \"No competitor covers migration from spreadsheets\",\n    \"Weak coverage of free tiers\"\n  ],\n  \"internal_link_ideas\": [\n    \"/blog/crm-vs-spreadsheet\",\n    \"/pricing\"\n  ]\n}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "f84168b0-54d7-4e13-bf35-d6cc9b7c18fc",
      "name": "Set Brief Format",
      "type": "n8n-nodes-base.set",
      "position": [
        1968,
        -64
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "e8ba3790-26ef-4de8-a894-96180d97190f",
              "name": "doc_title",
              "type": "string",
              "value": "=SEO Brief: {{ $('When Form Submitted').item.json.Keyword }}"
            },
            {
              "id": "a1b7ae06-2d55-4508-bd65-5ede157358ae",
              "name": "brief_markdown",
              "type": "string",
              "value": "=# SEO Content Brief: {{ $json.output.primary_keyword }}\n\n**Search intent:** {{ $json.output.search_intent }}\n**Target word count:** {{ $json.output.target_word_count }}\n\n## Title options\n{{ $json.output.title_options.map(t => '- ' + t).join('\\n') }}\n\n## Meta description\n{{ $json.output.meta_description }}\n\n## Recommended outline\n{{ $json.output.recommended_outline.map(s => '### ' + s.h2 + '\\n' + (s.h3 || []).map(h => '- ' + h).join('\\n')).join('\\n\\n') }}\n\n## Secondary keywords\n{{ $json.output.secondary_keywords.map(k => '- ' + k).join('\\n') }}\n\n## People also ask\n{{ $json.output.people_also_ask.map(q => '- ' + q).join('\\n') }}\n\n## Content gaps to win on\n{{ $json.output.content_gaps.map(g => '- ' + g).join('\\n') }}\n\n## Internal link ideas\n{{ $json.output.internal_link_ideas.map(l => '- ' + l).join('\\n') }}\n"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "6b73c933-86ec-40da-a850-a5ef61a6b6f4",
      "name": "Create SEO Document in Docs",
      "type": "n8n-nodes-base.googleDocs",
      "position": [
        2192,
        -64
      ],
      "parameters": {
        "title": "={{ $json.doc_title }}",
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "root",
          "cachedResultName": "/ (root)"
        },
        "operation": "create"
      },
      "typeVersion": 2
    },
    {
      "id": "456bc2c0-5f7c-4bf8-a036-86d1f71c5d29",
      "name": "Insert Content into Document",
      "type": "n8n-nodes-base.googleDocs",
      "position": [
        2416,
        -64
      ],
      "parameters": {
        "actionsUi": {
          "actionFields": [
            {
              "text": "={{ $('Set Brief Format').item.json.brief_markdown }}",
              "action": "insert"
            }
          ]
        },
        "operation": "update",
        "documentURL": "={{ $json.documentId }}"
      },
      "typeVersion": 2
    },
    {
      "id": "3bc26772-1264-4e1e-bc92-d41452a59e3f",
      "name": "Append Brief to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2640,
        -64
      ],
      "parameters": {
        "sheet": {
          "__rl": true,
          "mode": "list",
          "value": "Briefs"
        },
        "columns": {
          "value": {},
          "mappingMode": "autoMapInputData"
        },
        "options": {},
        "operation": "append",
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/REPLACE_ID/edit"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "a24e778d-6c09-4c81-8c48-1a1e3ceb04e2",
      "name": "Handle Insufficient SERP Data",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1232,
        384
      ],
      "parameters": {},
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Set Brief Format": {
      "main": [
        [
          {
            "node": "Create SEO Document in Docs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch SERP Results": {
      "main": [
        [
          {
            "node": "Split Organic Search Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Brief Model": {
      "ai_languageModel": [
        [
          {
            "node": "Generate SEO Content Brief",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "When Form Submitted": {
      "main": [
        [
          {
            "node": "Fetch SERP Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Output Parser Schema": {
      "ai_outputParser": [
        [
          {
            "node": "Generate SEO Content Brief",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Extract Page Headings": {
      "main": [
        [
          {
            "node": "Aggregate Competitor Signals",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Competitor Sites": {
      "main": [
        [
          {
            "node": "Extract Page Headings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate SEO Content Brief": {
      "main": [
        [
          {
            "node": "Set Brief Format",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check SERP Data Sufficiency": {
      "main": [
        [
          {
            "node": "Generate SEO Content Brief",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Handle Insufficient SERP Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create SEO Document in Docs": {
      "main": [
        [
          {
            "node": "Insert Content into Document",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Limit to Top 10 Competitors": {
      "main": [
        [
          {
            "node": "Fetch Competitor Sites",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Competitor Signals": {
      "main": [
        [
          {
            "node": "Check SERP Data Sufficiency",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert Content into Document": {
      "main": [
        [
          {
            "node": "Append Brief to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Organic Search Results": {
      "main": [
        [
          {
            "node": "Limit to Top 10 Competitors",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

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

About this workflow

This workflow collects a keyword via an n8n form, pulls the top Google results using SerpApi, scrapes headings from competitor pages, and uses OpenAI to generate a structured SEO content brief, which it saves to Google Docs and logs to Google Sheets. Receives a keyword, target…

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

More AI & RAG workflows → · Browse all categories →

Related workflows

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

AI & RAG

> *Trend-style celebrity selfie videos

Form Trigger, OpenAI Chat, Chain Llm +3
AI & RAG

The workflow runs every hour with a randomized delay of 5–20 minutes to help distribute load. It records the exact date and time a lead is emailed so you can track outreach. Follow-ups are automatical

Google Sheets, Agent, OpenAI Chat +5
AI & RAG

This workflow is perfect for graphic designers, creative agencies, marketing teams, or freelancers who regularly use AI-generated images in their projects. It's specifically beneficial for teams that

Google Sheets, Google Drive, HTTP Request +5
AI & RAG

This workflow is built for professionals and teams who want to scale their B2B outreach with context-rich, personalized communication. It automates the full prospect research process — from pulling le

OpenAI Chat, Chain Llm, Output Parser Structured +3
AI & RAG

This workflow is designed for professionals and teams seeking to scale their B2B research with comprehensive company intelligence. It automates the full prospect analysis process — from extracting con

Hunter, HTTP Request, Airtop +6