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 →
{
"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
}
]
]
}
}
}
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 →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
> *Trend-style celebrity selfie videos
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
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
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
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