I Built a Content Brief Agent in n8n That Produces Briefs I Actually Use — Full Workflow

Most AI-generated content briefs are useless for the same reason: they’re built from nothing but a keyword.
No SERP data. No competitor analysis. No understanding of what the top-ranking pages actually cover. The AI fills in what a content brief should look like based on its training — which means you get a template, not a strategy.
I had this problem for months. I was prompting ChatGPT for briefs and then spending 30 minutes cross-referencing competitor pages anyway to make them usable. The AI part saved me nothing.
So I built a proper n8n content brief agent. One that searches the actual SERP, reads the top-ranking pages, and generates a structured brief from that real data. Keyword in, Google Doc out, roughly 90 seconds.
This is the full build — every node, the prompt, and what the output looks like.
What’s in this post
- What the agent produces
- The workflow — overview
- Node by node
- The prompt
- Customizing it for your site
- Limitations (honest ones)
- FAQ
What the n8n content brief agent produces
Before the build, here’s the output — because a brief nobody uses is just a waste of 90 seconds.

Each brief includes:
- Target keyword + five semantic variations to use throughout the post
- Search intent label and a one-sentence explanation of why
- Three recommended title options (keyword-led, benefit-led, curiosity-led)
- Full H2/H3 outline with a one-line content note per section, based on what competitors actually cover
- Word count target estimated from the top three competitor pages
- People Also Ask questions pulled from the SERP
- Internal link suggestions — I feed the agent my site’s content clusters as context
- A competitor gap paragraph: what none of the top three pages covers, which this post could own
I still adjust the outline before writing — maybe 10 minutes of editing per brief. But I’m not building from zero anymore, and the outline is grounded in what’s actually ranking, not what the AI thinks should rank.
The workflow — overview
Eight nodes in total. The chain runs left to right:
Keyword Input → SERP Lookup → Format SERP → Fetch Top 3 Pages → Read Page Content → Merge Content → Generate Brief → Save to Google Doc
None of these require custom code beyond a small formatting script in node 3. If you’ve built anything with HTTP Request nodes in n8n before, this is straightforward.
Node by node
Node 1 — Keyword Input (Webhook)
A Webhook trigger node is the entry point. I call it from a bookmarklet I added to my browser — one click when I’m looking at a keyword in Ahrefs, and it fires the webhook with the keyword and a short site context note.
The POST body looks like this:
{
"keyword": "n8n wordpress integration",
"site_context": "beginner tutorials for WordPress bloggers using n8n automation"
}
You can trigger it from a form, a Google Sheet, or n8n’s own test input panel. The webhook is just the entry point — it doesn’t matter how you call it.
Node 2 — SERP Lookup (HTTP Request → SerpAPI)
An HTTP Request node hits the SerpAPI search endpoint with the keyword from node 1. It returns the top 10 organic results — title, URL, snippet, and position for each.
SerpAPI’s free tier covers 100 searches per month, which is enough for regular use. If you’re generating briefs at higher volume, their paid tiers start at $50/month. Alternatively, ValueSERP and DataForSEO both work as drop-in replacements — the node setup is identical, only the endpoint and parameter names change.
Node 3 — Format SERP (Code)
A JavaScript Code node that takes the organic results array and converts it into a plain text block the AI can actually read. Each result becomes one line:
// n8n Code node — Format SERP results for AI input
const results = $input.first().json.organic_results;
const formatted = results.slice(0, 10).map((r, i) =>
`Position ${i + 1}: ${r.title} — ${r.snippet} — URL: ${r.link}`
).join('\n');
return [{ json: { serp_text: formatted } }];
The AI uses the titles and snippets more than the URLs — they signal what subtopics and angles Google is currently rewarding for this keyword.
Node 4 — Fetch Top 3 Pages (Split In Batches)
Takes the top 3 URLs from the SERP results and feeds them one at a time to node 5. I limit to 3 pages for two reasons: the top 3 positions carry the strongest signal for what Google rewards right now, and fetching more significantly increases the token count going into the AI node — raising cost and risking context limit errors.
Node 5 — Read Page Content (HTTP Request → Jina Reader)
Calls https://r.jina.ai/ + the competitor URL for each of the top 3 pages. Jina Reader converts any page into clean markdown — no navigation, no footer, no ads. It’s the fastest way to get competitor content into n8n without building a scraper.
Jina’s free tier is generous enough for regular brief generation. The node runs three times — once per batch item from node 4 — and outputs the full page text each time.
Node 6 — Merge Content (Aggregate)
Collects the three Jina responses into a single item so the AI node receives all competitor content in one input. I also truncate each page’s content to 3,000 characters inside this node using an n8n expression — this keeps the total token count manageable without losing the most relevant content, which tends to appear early in well-structured posts.
Node 7 — Generate Brief (AI Agent → GPT-4o)
The main node. I use n8n’s AI Agent node with GPT-4o as the model. The system prompt (in the next section) receives the keyword, site context, formatted SERP, and merged competitor content as inputs via expressions.
Output is a structured markdown brief. GPT-4o follows the format instructions reliably — I’ve had maybe 3 malformed outputs across 60+ briefs, both fixable by re-running.
Node 8 — Save to Google Doc (Google Docs)
Creates a new Google Doc in a designated “Content Briefs” folder in Drive. Title is set as Brief — {{ $('1. Keyword Input').item.json.keyword }}. The AI output from node 7 goes straight into the document body.
I also have a ninth node — a Slack message with the Doc URL — that I didn’t count in the original eight because it’s optional. Add it if you want a notification when the brief is ready.
The prompt
This is the part most workflow tutorials skip, and it’s where the brief goes from generic to useful. The nodes are just plumbing — the prompt is the actual work.
You are a senior SEO content strategist. You have been given:
1. A target keyword
2. The top 10 SERP results for that keyword (titles, snippets, URLs)
3. The full text of the top 3 ranking pages
Your task is to produce a content brief for a blog post targeting this keyword.
The brief is for a blog called TopTut that publishes beginner-to-intermediate
tutorials on WordPress, n8n automation, and AI tools for content creators.
Return the brief in this exact structure — no deviation, no preamble:
## Content Brief: [keyword]
**Target keyword:** [keyword]
**Semantic variations:** [5 related phrases the reader might search]
**Search intent:** [Informational / Commercial / Transactional] — [one sentence explaining why]
**Recommended word count:** [estimate based on average length of top 3 competitor pages]
---
## Title options (choose one to use)
1. [Lead with keyword]
2. [Lead with primary benefit]
3. [Lead with curiosity or angle the competitors haven't used]
---
## Outline
### Introduction
[What the intro must address — the reader's problem and what this post promises to solve]
### [H2 — main subtopic 1]
[One sentence: what this section covers and why it earns its place in the outline]
### [H2 — main subtopic 2]
[Continue for all major subtopics the top-ranking pages cover]
### [H3s under each H2 where needed]
[Only add H3s where the top-ranking pages go into meaningful sub-sections]
---
## People Also Ask
[4-6 questions from the SERP or logically related to the topic that the post should answer]
---
## Internal linking opportunities
[2-3 internal link anchors this post should target, given the site covers WordPress,
n8n automation, and AI tools. Format: "anchor text" → topic the linked page should cover]
---
## Competitor gap
[One paragraph: what the top 3 ranking pages do NOT cover that this post could cover
as a competitive differentiator. Be specific — name the gap, not just "add more depth."]
---
Base your outline entirely on what the top-ranking pages actually cover.
Do not suggest sections based on general SEO advice — only on the real SERP evidence provided.
The last two lines are the most important part of the prompt. Without them, the AI defaults to generating a generic outline that could have come from any keyword. With them, the outline reflects what Google is actually rewarding right now for that specific search.
Customizing it for your site
The site_context field in the webhook payload is the main variable between briefs. For WordPress tutorial posts I send a different context than for n8n workflow posts — the internal linking suggestions and competitor gap analysis shift accordingly.
A few other changes worth making once the base workflow is running:
- Exact word count targets. Right now the AI estimates from content volume. You can get precise numbers by extracting character counts from each Jina-fetched page in node 6 and calculating an average before it reaches the AI.
- Output format. Swap the Google Docs node for Notion, a WordPress draft via the REST API, or a Slack message with the brief pasted inline. The AI output doesn’t change — only the final node does.
- Batch mode. Trigger from a Google Sheet instead of a webhook. Add a Loop node that iterates through a column of keywords and creates one Doc per row. Useful for planning a full content calendar at once.
Limitations — the honest ones
Jina Reader is rate-limited. The free tier handles a few briefs per day without issue. If you’re running this at higher volume, add an error-handling branch that retries after 10 seconds when a Jina call returns empty. I’ve had this happen during bursts of 10+ briefs in a row.
SerpAPI localizes results. The SERP you get depends on your country and language settings in the API parameters. If you’re targeting a specific market, set gl and hl explicitly in the HTTP Request node — otherwise you may be analyzing competitors your actual readers don’t see.
The AI can’t verify word counts. It estimates from content density, not a real character count. The estimate is close enough for planning but not exact. Use the calculation improvement in node 6 if accuracy matters for your process.
It doesn’t replace editorial judgment. The outline will occasionally miss a section that matters for your specific audience, or include a competitor section that doesn’t fit your angle. I read every brief before writing — the 10 minutes of adjustments is what makes the brief mine, not just a document the workflow produced.
Frequently asked questions
What does an n8n content brief agent actually do?
It takes a keyword, searches Google via an API, reads the top-ranking pages, and generates a structured content brief using an AI model. The output includes a title, outline, word count target, PAA questions, and competitor gap analysis — all grounded in real SERP data rather than generic AI assumptions.
Do I need SerpAPI specifically?
No. Any API that returns organic SERP results works — ValueSERP, DataForSEO, and Google Custom Search JSON API are all drop-in options. The node just needs to return titles, URLs, and snippets. SerpAPI has the most straightforward free tier to get started with.
Can I run this on n8n cloud instead of self-hosted?
Yes. The workflow runs identically on n8n cloud. Self-hosting gives you more control over execution timeouts (the Jina fetch calls occasionally take 8–10 seconds each, which matters if your cloud plan has tight limits), but for most use cases cloud works fine.
How much does it cost per brief?
At current GPT-4o pricing, between $0.02 and $0.08 per brief depending on how much competitor content makes it into the prompt. SerpAPI free tier covers 100 searches per month. Jina Reader is free. Google Docs is free. The AI node is the only real cost, and at publishing volumes it’s negligible.
Can I generate briefs for multiple keywords at once?
Yes — trigger from a Google Sheet with a keyword column instead of a webhook. Add a Loop node before the SERP Lookup step. Each row triggers the full chain and outputs a separate Google Doc. I use this at the start of a content sprint when I’m planning six to eight posts at once.
The workflow itself took about a day to build and a few more hours of prompt iteration to get the output to a standard I’d actually write from. The nodes are the easy part. Getting the prompt to produce outlines that are genuinely specific — not just plausible-sounding — took the most time.
If you build a version of this and change something that improves the output, drop a comment. The competitor gap section in particular feels like it still has room to be sharper.

