An n8n workflow that takes one raw idea in and produces a coordinated LinkedIn post, X thread, newsletter, carousel plan and short-form script out, all traceable to the same idea and campaign record, with nothing publishing until a human approves it.

Built for content leads and solo operators who have one good idea and no reliable way to turn it into a full multi-platform campaign without losing a week to manual drafting.

<aside> ⚡

Want your version wired up and running, with your own tools and approval flow already loaded? Talk to UGC Ninja

</aside>


What is in this build

<aside> 📁


The node map

# Node Type Purpose
1 Idea Intake Webhook / Form Trigger Captures the raw idea, source, and campaign name
2 Create Campaign Record Airtable/Postgres Insert Opens the campaign row, generates campaign_id
3 Audience Research HTTP Request + AI node Pulls recent engagement signals tied to the idea's topic
4 Angle Selection AI node Proposes 3 angles, scores them, picks one with reasoning
5 Core Argument Development AI node Builds the argument skeleton every output will share
6 Split NoOp / Split In Batches Fans the argument out to five drafting nodes at once
7a LinkedIn Drafting AI node Full post draft
7b X Thread Creation AI node 6 to 10 tweet thread
7c Newsletter Drafting AI node Section-based newsletter draft
7d Carousel Planning AI node Slide-by-slide plan, text only
7e Short-Form Scripting AI node 30 to 60 second script with beats
8 Creative Briefing AI node One brief per visual asset needed
9 Merge Merge node Recombines all five outputs under one campaign_id
10 Quality Control AI node Checks every output against the QC rubric
11 Human Approval Gate Wait node + Slack/Email Sends all outputs to a reviewer, halts until a response arrives
12 Scheduling HTTP Request Only fires on approval, writes schedule times back to the record
13 Performance Tracking Cron + HTTP Request Pulls engagement stats on a schedule, writes back to the campaign row

<aside> 📁

Branch logic. Node 6 splits into five parallel branches (7a-7e) that all read the same core_argument field from node 5, so a change to the argument never has to be copied five times. Node 9 merges on campaign_id, not on timing, so a slow branch never gets dropped.

</aside>

<aside> ⚠️

Retry rules. Every AI node gets 3 retry attempts, exponential backoff starting at 10 seconds. A node that fails all 3 writes status: failed_node_X to the campaign record and the workflow stops rather than continuing with a gap.

Error handling. A separate Error Trigger workflow watches the main one, posts any unhandled failure to a Slack error channel with the campaign_id and failed node name, and sets the campaign record to needs_attention. Nothing retries automatically past 3 attempts, because a silent retry loop on a broken prompt burns credits for no output.

</aside>


The database schema

One table, campaigns, is the spine. Every output row links back to it by campaign_id, which is what keeps five parallel drafts traceable to the one original idea.

campaigns

Field Type Notes
campaign_id Auto-number / UUID Primary key
raw_idea Long text The original input, never edited
source Single select Call, article, brainstorm, client
angle_chosen Text From node 4
core_argument Long text From node 5
status Single select drafting, qc, awaiting_approval, approved, scheduled, published, needs_attention
approved_by Text Filled at node 11
approved_at Date

outputs — one row per platform, per campaign

Field Type Notes
output_id UUID Primary key
campaign_id Link to campaigns Foreign key
platform Single select LinkedIn, X, Newsletter, Carousel, Short-form
draft_text Long text
qc_result Single select Pass, Flagged
scheduled_time Date/time Written by node 12, blank until approved
published Checkbox

<aside> 📁

Required to trigger the workflow: raw_idea and source. Everything else populates as the workflow runs. No output node fires without a valid campaign_id.

</aside>