This workflow corresponds to n8n.io template #10813 — we link there as the canonical source.
This workflow follows the Agent → OpenAI Chat 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": "b8e73760-245e-4265-bbca-4b82f82b7758",
"name": "When clicking \u2018Execute workflow\u2019",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-224,
96
],
"parameters": {},
"typeVersion": 1
},
{
"id": "e0527391-e9fe-45c4-95f3-192a98690782",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
240,
320
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "gpt-4o-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "ca7b3775-810c-4ab3-9d19-362e81c23e77",
"name": "Structured Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
368,
320
],
"parameters": {
"jsonSchemaExample": "{ \"topic\": \"string\", \"subtopics\": [ { \"subtopic\": \"string\", \"details\": \"string\" } ] } "
},
"typeVersion": 1.3
},
{
"id": "8c7a681e-fc37-43e7-9f0b-99cbf75a106b",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
800,
96
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "34aa06eb-a8ab-48c5-af40-dee391965b62",
"name": "AI Agent1",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1024,
96
],
"parameters": {
"text": "=The outline refers to parts of a conversation.\nThis is the article section that covers these topics:\n\nSubtopic: {{ $json.subtopic }}\nDetails: {{ $json.details }}\n\nWrite a maximum of 1 paragraph.\nDo not number any sections.\nInclude a lot of detail.\n\nMandatory Rules\n\n1. Do not add numbering in any part.\n2. Write with detail and dense information.\n3. Ensure more than 75 percent of sentences contain a maximum of 20 words to meet YOAST SEO readability standards.\n4. Ensure the keyword \"{{ $('Input Topic Plans').item.json.Keyword }}\" appears in the sentences.\n5. Use clear and active sentences.\n6. Use 1 or 2 transition words recognized by YOAST. Examples: so, therefore, however, besides that, then, after that, for example.\n7. Avoid emojis, excessive punctuation, and promotional style.\n8. Do not use em dashes to keep the writing natural and not AI generated.\n9. Write in {{ $('Input Topic Plans').item.json.Language }} Language",
"options": {
"systemMessage": "You are a wise expert writer who shares an abundance of detail and examples, covering niche subtopics and rarely known small details."
},
"promptType": "define"
},
"typeVersion": 3
},
{
"id": "05a44cb4-15de-41a2-9a41-cca190feb4aa",
"name": "OpenAI Chat Model1",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
1040,
320
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "gpt-4o-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "5bd8b8be-6dfe-4616-84f2-db71be3bf1fd",
"name": "Aggregate",
"type": "n8n-nodes-base.aggregate",
"position": [
1088,
-208
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData"
},
"typeVersion": 1
},
{
"id": "be01bbe2-5cb6-41c7-842a-68dce304c87c",
"name": "Simple Memory",
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
"position": [
1168,
320
],
"parameters": {
"sessionKey": "={{ $('Loop Over Items').item.json.details }}",
"sessionIdType": "customKey"
},
"typeVersion": 1.3
},
{
"id": "687db5eb-d6cd-4c2a-8d7d-555b346ee2d0",
"name": "Create New Array",
"type": "n8n-nodes-base.code",
"position": [
1376,
224
],
"parameters": {
"jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nfor (const item of $input.all()) {\n item.json.subtopic = $('Loop Over Items').first().json.subtopic\n}\n\nreturn $input.all();"
},
"typeVersion": 2
},
{
"id": "2d2291b6-8818-40cd-99dd-8ea8a5044d30",
"name": "JSON HTML",
"type": "n8n-nodes-base.code",
"position": [
1376,
-208
],
"parameters": {
"jsCode": "// Input contoh: { title, article: [{subtopic, output}, ...] }\nconst title = $('Generate Outline').first().json.output.topic;\nconst items = Array.isArray($input.first().json.data) ? $input.first().json.data: [];\n\nconst norm = (v) => (v ?? '').toString().trim();\nconst para = (t) => t\n .split(/\\n{2,}/).map(s => s.trim()).filter(Boolean)\n .map(s => `<p>${s}</p>`).join('\\n');\n\nlet md = '';\nlet html = '';\n\n// 1) Item pertama: hanya output\nif (items[0]) {\n const out0 = norm(items[0].output);\n if (out0) {\n md += `${out0}\\n\\n`;\n html += para(out0) + '\\n\\n';\n }\n}\n\n// 2) Sisanya: subtopic lalu output\nfor (let i = 1; i < items.length; i++) {\n const st = norm(items[i].subtopic);\n const out = norm(items[i].output);\n\n if (st) {\n md += `## ${st}\\n\\n`;\n html += `<h2>${st}</h2>\\n`;\n }\n if (out) {\n md += `${out}\\n\\n`;\n html += para(out) + '\\n\\n';\n }\n}\n\n// Optional: ringkas spasi\nmd = md.replace(/\\n{3,}/g, '\\n\\n').trim();\nhtml = html.replace(/\\n{3,}/g, '\\n\\n').trim();\n\n// Keluaran untuk node berikutnya (HTTP Request -> WordPress)\nreturn [\n {\n json: {\n title,\n content_markdown: md,\n content_html: html, // for Rest API\n }\n }\n];\n"
},
"typeVersion": 2
},
{
"id": "b77d1b0a-0252-499a-8b77-769a12fa291f",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-624,
-80
],
"parameters": {
"width": 336,
"height": 560,
"content": "## Article Generator SEO Friendly\n\n### How it works:\n\u2022 Generates a structured outline from your topic using an AI Agent.\n\u2022 Loops through each subtopic and expands it into a detailed, SEO-friendly paragraph.\n\u2022 Combines everything into two final outputs. A clean JSON object and a Markdown version.\n\u2022 Content is tested in Yoast SEO and achieves Good readability.\n\u2022 Uses GPT-4o Mini by default. Token usage is usually 2000 to 3000 depending on the number of outline items.\n\n### Set up steps\n\u2022 Prepare your OpenAI API Key.\n\u2022 Adjust the topic, outline count, language, and keyword as needed in teh *Edit Fields*.\n\u2022 Change the model anytime if you want different quality or token usage."
},
"typeVersion": 1
},
{
"id": "e640a067-78a9-4256-a70e-b293677cbfa5",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
736,
16
],
"parameters": {
"color": 7,
"width": 896,
"height": 448,
"content": "## 2. Loop the Outline and Generate Paragraph\nWe also using simple memory to make sure the loop still relevant"
},
"typeVersion": 1
},
{
"id": "724d69a1-a553-48c6-a445-d92fbd423d6d",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1040,
-352
],
"parameters": {
"color": 7,
"width": 624,
"height": 320,
"content": "## 3.Result become JSON with Markdown and HTML format\nJust continue this nodes with your purpose"
},
"typeVersion": 1
},
{
"id": "db82eca5-32b4-4435-a864-d0ccf9db7c81",
"name": "Generate Outline",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
224,
96
],
"parameters": {
"text": "=Write a creative outline max {{ $json[\"How many outline?\"] }} item on {{ $json.Topic }} in {{ $json.Language }} language. \n\nOutput a JSON object with the following structure: { \"topic\": \"string\", \"subtopics\": [ { \"subtopic\": \"string\", \"details\": \"string\" } ] } Start the subtopic with an Introduction and end with a Conclusion.",
"options": {
"systemMessage": "You are a wise expert writer who fluent with Bahasa Indonesia and has broad knowledge ranging from general overview to niche subtopics, including rarely known small details."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 3
},
{
"id": "ee209bbb-6bf5-4d6b-ae22-83aece5887d0",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-48,
16
],
"parameters": {
"color": 7,
"width": 752,
"height": 448,
"content": "## 1. Creating Outline"
},
"typeVersion": 1
},
{
"id": "c13a47ac-8e53-4c71-ad7b-8896524a8938",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-624,
-544
],
"parameters": {
"width": 336,
"height": 400,
"content": "## Workflow Creator Profile \u2013 Pake.AI\n\n**Pake.AI** is an AI Enabler from Indonesia, committed to helping creators, entrepreneurs, and businesses automate their operations through practical and accessible AI solutions.\n\nThis workflow is shared **for free** to support the community and accelerate AI adoption.\n\nIf you have any questions about this workflow or want to explore more automation tools, feel free to contact us:\n\n\ud83c\udf10 **https://pake.ai**\n"
},
"typeVersion": 1
},
{
"id": "f6da2439-4e85-4fc4-b018-99fd12f61dae",
"name": "Input Topic Plans",
"type": "n8n-nodes-base.set",
"position": [
0,
96
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "11ae2bc0-2188-4392-85b5-4c05afc2d7f4",
"name": "Topic",
"type": "string",
"value": "Input your topic Here"
},
{
"id": "6a4a8161-5dad-433d-9cb0-900377b8b66f",
"name": "How many outline?",
"type": "number",
"value": 3
},
{
"id": "1a9d9e94-7610-49aa-9a0e-703eebc34ee1",
"name": "Language",
"type": "string",
"value": "Input the language here (ex: English/Indonesia/Arabic/etc)"
},
{
"id": "345e7e1f-f980-4140-849c-4150b903ab9f",
"name": "Keyword",
"type": "string",
"value": "Put your keyword here"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "0bbbe751-95c1-413a-81a1-beb3163907ab",
"name": "Get Subtopic Array (For Looping)",
"type": "n8n-nodes-base.code",
"position": [
576,
96
],
"parameters": {
"jsCode": "// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nreturn $input.first().json.output.subtopics"
},
"typeVersion": 2
}
],
"connections": {
"AI Agent1": {
"main": [
[
{
"node": "Create New Array",
"type": "main",
"index": 0
}
]
]
},
"Aggregate": {
"main": [
[
{
"node": "JSON HTML",
"type": "main",
"index": 0
}
]
]
},
"Simple Memory": {
"ai_memory": [
[
{
"node": "AI Agent1",
"type": "ai_memory",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[
{
"node": "Aggregate",
"type": "main",
"index": 0
}
],
[
{
"node": "AI Agent1",
"type": "main",
"index": 0
}
]
]
},
"Create New Array": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Generate Outline": {
"main": [
[
{
"node": "Get Subtopic Array (For Looping)",
"type": "main",
"index": 0
}
]
]
},
"Input Topic Plans": {
"main": [
[
{
"node": "Generate Outline",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Generate Outline",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"OpenAI Chat Model1": {
"ai_languageModel": [
[
{
"node": "AI Agent1",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "Generate Outline",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Get Subtopic Array (For Looping)": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"When clicking \u2018Execute workflow\u2019": {
"main": [
[
{
"node": "Input Topic Plans",
"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.
openAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow converts a single topic into a full blog article through a structured multi-step process. Instead of generating everything in one pass, it breaks the task into clear stages to produce cleaner structure, better SEO consistency, and more predictable output quality.…
Source: https://n8n.io/workflows/10813/ — 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.
Digital marketers, content creators, social media managers, and businesses who want to use AI marketing automation for YouTube Shorts without spending hours on production. This AI workflow helps anyon
Unlock the Power of Language with Personalized AI Learning! MOTION TUTOR is a revolutionary AI-powered language learning platform that adapts to your progress and guides you from basic vocabulary to c
This automation is designed to help you generate AI-powered music tracks, cover art, and fully rendered music videos — all triggered from a simple Telegram chat and managed via Google Sheets.
This workflow serves as a comprehensive "Workflow Nodes SEO & Documentation Generator". It uses AI to analyze, rename, and document n8n workflows, offering a streamlined way to optimize workflow reada
Template Carnaval - time instagram. Uses toolWorkflow, lmChatOpenAi, memoryBufferWindow, agent. Event-driven trigger; 56 nodes.