I used to spend the first hour of every workday doing the same thing: copy a draft from my notes, open Twitter, paste, tweak. Open LinkedIn, paste, tweak. Open Instagram, paste, tweak the caption, switch to my phone because the desktop uploader was being weird. Then realize I’d missed the LinkedIn version’s first line getting truncated in the feed preview.
Five platforms.
Five tabs.
Same content, five slightly different shapes.
Every single morning.
So I built a workflow that does all of it while I’m still on my first coffee. It uses Claude to write the posts, n8n to orchestrate the pipeline, and a scheduling API to actually hit publish across every platform from one HTTP call. Total monthly cost: under $70. Setup time the first weekend: about three hours.
This is the build. I’ll walk through what’s in it, why each piece is there, and where I think most tutorials in this space cut corners.
Why I didn’t just use Buffer and Zapier
Fair question, and the answer is “I tried.” Buffer plus Zapier works fine if your needs are simple. The reason I outgrew it:
- Buffer’s free tier caps at 3 channels and 10 scheduled posts. Their team plan jumps to $100/mo when you want anything resembling automation.\
- Zapier’s per-action pricing gets ugly fast once you’re running 5+ steps per post.\
- The big one: I wanted per-platform customization that an LLM controls, not the same caption shoved into every channel with hashtags appended. Buffer’s AI assistant doesn’t know my voice. Claude does, because I wrote the system prompt.
The stack I landed on:
- Claude writes platform-specific versions of each post in one API call\
- n8n glues everything together (free if you self-host, $24/mo on their cloud starter)\
- A scheduler with an API handles the actual publishing and I use SchedPilot because it covers the ten platforms I care about and exposes a proper REST API on its Platinum tier, something like $39/month for connecting 10+ social media accounts; the same pattern works with any API-first scheduler\
- Google Sheets as a dumb but reliable state tracker
About $50–70/month all-in. That’s the number to beat.
What you’ll need before you start
- An n8n account. Cloud is fine for testing, self-host if you’re cost-sensitive or want everything on your own infrastructure.\
- An Anthropic API key for Claude. Pay-as-you-go is plenty, even at 50 posts a month, I rarely spend more than $5 in API costs.\
- A scheduler that exposes an API. As mentioned, I use SchedPilot’s Platinum plan for this. The point is which platforms it covers and whether you can POST to it from n8n, pick whatever fits your stack.\
- A Google account for Sheets. Optional but I strongly recommend it as your content log.\
- Your social accounts connected once inside your scheduler. This is the one-time OAuth pain, you do it once in the scheduler’s UI and never think about it again. (This is the bit that makes the API-scheduler approach work for solo creators. Trying to authenticate against Instagram Graph API or TikTok’s API as a single developer is genuinely miserable.)
The workflow, at a glance
Here’s the shape of what we’re building:
- Trigger — a cron schedule, or a new row in Google Sheets, or a webhook\
- Topic selection — either you provide it, or Claude picks from a list\
- Claude generates platform-specific captions in a single call, returned as JSON\
- (Optional) Image generation per platform aspect ratio\
- Log to Google Sheets so you can see what’s queued and what shipped\
- POST to the scheduler API — one call, one auth, posts to every connected platform\
- Confirmation back to Sheets or Slack
That’s the whole thing. Seven nodes. Less than the number of tabs I used to have open.
Step 1: Set up your trigger
In n8n, drop a Schedule Trigger onto the canvas. I run mine at 8 AM local time on weekdays. If you want to be more clever, use a Google Sheets trigger that fires when you add a row with status “ready” , that lets you queue up topics in batches whenever you have a brain wave, and the workflow picks them up automatically.
For testing, just use a manual trigger. Get the rest working first, then swap in the schedule.
Step 2: Connect Claude as your content writer
This is the part that makes everything else worth doing. The trick is to ask Claude for every platform’s version in a single call and have it return structured JSON. One API call, multiple platform-specific outputs, no manual reformatting.
In n8n, add an HTTP Request node and configure it to hit Anthropic’s messages endpoint. The system prompt is where the magic lives — this is the one I use:
You are a social media manager for [BRAND]. Given the topic below, write\
one post for each of the following platforms, optimized for that platform's\
norms and audience:
- twitter: 240 chars max. Hook in the first 10 words. 1-2 hashtags only.\
- linkedin: 1200-1800 chars. Three-line opener before the "...more" cutoff.\
Professional but not corporate. Personal POV welcome.\
- instagram: 1-3 sentence caption. Add 10 hashtags in a single line at the end.\
- tiktok: 80-120 chars. Hook-driven. No corporate language.\
- threads: 2-4 short sentences. Conversational. Max one hashtag.
Voice: [PASTE YOUR VOICE GUIDE HERE — 3-5 lines is enough]
Return as JSON with this exact shape:\
{\
"twitter": "...",\
"linkedin": "...",\
"instagram": "...",\
"tiktok": "...",\
"threads": "..."\
}
No commentary. Just the JSON.\
The actual API call from the n8n HTTP Request node looks like this:
bash
curl https://api.anthropic.com/v1/messages \\
--header "x-api-key: $ANTHROPIC_API_KEY" \\
--header "anthropic-version: 2023-06-01" \\
--header "content-type: application/json" \\
--data '{\
"model": "claude-opus-4-7",\
"max_tokens": 2000,\
"system": "[your system prompt above]",\
"messages": [\
{"role": "user", "content": "Topic: [topic from your trigger]"}\
]\
}'\
Set the n8n HTTP Request node to use header authentication, paste your Anthropic key into x-api-key, set the body to JSON, and you’re done.
Two things worth knowing here:
- Tell Claude exactly what JSON shape you want. Don’t say “return JSON” and hope. Specify the keys. n8n’s downstream nodes need to reference
{{$json.content[0].text}}and then parse the JSON inside so easier when the shape is deterministic.\ - Put your voice guide in the system prompt, not the user message. This stays the same across every post, which means Claude’s caching kicks in and the calls get cheaper after the first one.
Step 3: (Optional) Generate platform-specific images
Skip this if you’re text-only. If you want images, add another HTTP Request node calling OpenAI’s image API (or whatever model you prefer). The thing to remember is aspect ratio per platform: 1:1 works for Instagram feed and LinkedIn, 9:16 for Stories and TikTok, 16:9 for Twitter and YouTube thumbnails.
I usually generate one square image and let the scheduler crop. It’s not perfect, but generating five aspect-ratio variants per post triples your image API spend for marginal improvement.
Step 4: Log everything to Google Sheets
Add a Google Sheets node. Append a row with these columns:
| timestamp | topic | twitter_text | linkedin_text | instagram_text | tiktok_text | threads_text | image_url | sched_id | status |
The sched_id and status columns get filled in after Step 5. This sheet is your content calendar, debug log, and post archive in one. The first time something breaks at 8 AM and you can’t remember what topic was queued, this sheet is what saves you.
Step 5: Post to every platform with one API call
This is the step that justifies the whole stack.
The naive version of this workflow ends with five HTTP Request nodes in parallel — one for Twitter API, one for LinkedIn API, one for Instagram Graph API, one for Facebook, one for TikTok. Each needs its own OAuth flow, its own credentials in n8n, its own body shape, its own rate limits, its own error handling. I tried this. I rebuilt it twice. Instagram’s Graph API requires a business account and an approved app for posting; TikTok’s API is similarly gatekept. As a solo creator, you spend days authenticating instead of shipping.
The version that actually works for indie hackers is to delegate the publishing to a scheduler that’s already done the platform OAuth work. One HTTP Request node, one Bearer token, one body shape, every platform.
The call looks roughly like this (exact shape varies per scheduler):
- Method: POST\
- URL: the scheduler’s posts endpoint\
- Auth: Bearer token in the header\
- Body: JSON containing your post text per platform (or one universal text), the image URL, the platforms to publish to, and either
publish_now: trueor aschedule_attimestamp
If you set a schedule_at value, the post sits in the scheduler’s queue and goes out at the time you specify and useful when you want to batch-generate content on Monday and have it drip out across the week. If you set publish_now, it goes immediately.
Map the values from your Sheets node (or directly from Claude’s output) into the body. One node. Five-plus platforms.
Step 6: Add a human checkpoint (optional, but I keep it)
I put a Slack node between Claude and the scheduler. It DMs me a preview of all the platform variants with two buttons: “ship it” and “skip.” Claude is great but it’s not perfect, and the cost of catching one weird hallucinated stat before it goes to LinkedIn is about five seconds of my time.
If you’re more confident in your prompt than I am, skip this and let it run autonomously. Just have a Slack alert wired up for failures.
Step 7: Activate and let it run
Flip the workflow to active in n8n. Add a Slack or email alert on workflow errors. Check the Sheets log once a week to make sure nothing’s silently failing.
That’s it. That’s the whole system.
What breaks in production
Tutorials always show the happy path. Here’s what actually fails and what I do about it:
- Claude returns malformed JSON. Rare, but it happens but usually when the topic contains characters that confuse the JSON serialization. Wrap the parse in n8n’s error handling and have it retry with a “return ONLY valid JSON” reminder appended.\
- Image dimensions get rejected. Instagram especially is picky. If you’re generating images, validate dimensions before posting or let the scheduler handle the crop.\
- LinkedIn truncates in the feed at ~210 characters before the “…more” link. Even if the API accepts 3000 characters, your hook needs to land in the first three lines. Tell Claude this explicitly in the system prompt.\
- Rate limits on Claude. If you’re batch-generating dozens of posts at once, add a Wait node between iterations. The free tier rate limits will bite you otherwise.\
- OAuth tokens expire. If your scheduler’s connected social accounts disconnect (which they do every few months for most platforms), your posts silently fail. The fix is a weekly health check , I have a separate n8n workflow that pings the scheduler API every Monday and Slacks me if any platform is disconnected.
What it actually costs
Real numbers from my own bill:
| Component | Tier | Monthly |
| Claude API | pay-as-you-go | ~50 posts/mo |
| n8n | Self-hosted on $5 VPS | $5 |
| Scheduler API access | Almost all tiers expose the API | ~ $30-40 |
| OpenAI image gen (optional) | ~50 images | ~$2 |
| Total | ~$45-55/mo |
A part-time social media VA runs $400–800/mo. An agency starts at $2K. I’m not saying this replaces a human strategist and it doesn’t, and Claude isn’t going to come up with your next big campaign idea , but for the publishing layer, the math is pretty clear.
Where to take this next
Once the basic workflow is running, the obvious upgrades:
- Trend discovery. Add a Perplexity or Tavily node before Claude that pulls trending topics in your niche. Claude picks the best one. You wake up to fresh, timely posts you didn’t have to ideate.\
- A/B variant generation. Have Claude generate three versions of each platform’s post. Post the strongest, save the others. After a month of engagement data, feed the winners back as examples in your system prompt.\
- Engagement loop. Pull post performance data (likes, replies, shares) back into Sheets daily. Once you have a few hundred data points, you can start asking Claude to write posts in the style of your top performers.\
- Video. If you want AI-generated avatar videos in the mix, HeyGen has an API for that and slots in cleanly between Claude (script) and the scheduler (publish). I haven’t gone that deep yet but the pattern is straightforward.
Honest answers to questions people ask me about this
“Doesn’t this make all your content sound like AI?” Only if your prompt is lazy. The voice guide section of the system prompt is the single most important part — spend a real afternoon on it. Read your last 20 posts that actually performed well, pull out what makes them sound like you, and codify that. Mine is about 8 lines. It’s the difference between “ChatGPT wrote this” and content that sounds like me.
“Why not just use Make.com or Pipedream?” Same shape, different tool. Use whichever you already know. n8n’s edge for me is that it self-hosts and the canvas is easier to reason about when workflows get complex.
“Does any of this actually grow an audience?” Posting consistently grows an audience. This workflow makes posting consistently possible when you have a day job and 14 other things on fire. It’s not a growth hack , it’s a removal of the friction that was stopping you from being consistent in the first place.
“What about engagement and comments? Can this reply for me?” It can, but I don’t recommend it for solo creators. Comments are where actual relationships form. Let the AI handle the broadcast layer, keep the conversation layer human.
If you build this and something breaks, the n8n community forum is where I’d start , there’s already a thread or two about exactly this pattern. And if you want the template I’m running, I’ll probably put a sanitized version on GitHub at some point. Drop a comment if that’d be useful and I’ll prioritize it.

