How to Automate Social Media Posting with n8n

Use the official Postproxy n8n integration to publish to TikTok, Threads, Pinterest, and 6 more platforms from any workflow.

What’s missing in n8n’s native nodes

PlatformNative n8n node
X (Twitter)Yes, works
LinkedInPersonal only — company page is HTTP Request
FacebookPage posts; no Reels or Stories
InstagramRead-only; no Reels publish
TikTokNone
YouTubeUpload only; no Shorts auto-detection
ThreadsNone
PinterestNone
BlueskyNone

The realistic options: maintain HTTP Request nodes per platform with their per-platform OAuth, or use one node that abstracts all of them.

The Postproxy n8n integration

Postproxy is listed on n8n’s integrations directory. The integration is HTTP Request-based with credentials stored once and reused across workflows.

Setup:

  1. In n8n: Credentials → New → HTTP Header Auth (or HTTP Request with bearer auth)
  2. Name: “Postproxy”
  3. Header name: Authorization
  4. Header value: Bearer YOUR_POSTPROXY_API_KEY

Then any HTTP Request node calling https://api.postproxy.dev/api/... reuses that credential.

For the official integration page, see postproxy.dev/automation/n8n and the integration listing on n8n.io.

Example workflow: RSS → social

A blog publishes a new post; the workflow scrapes the RSS feed, formats a caption, attaches the OG image, and posts to Instagram, LinkedIn, Threads, and X:

[RSS Trigger]
→ [Set node]
caption = `${title}\n\n${summary}\n\nRead more: ${link}`
image = `${ogImage}`
→ [HTTP Request: Postproxy]
Method: POST
URL: https://api.postproxy.dev/api/posts
Auth: Postproxy credential (header)
Body (JSON):
{
"post": { "body": "{{ $json.caption }}" },
"profiles": ["instagram", "linkedin", "threads", "twitter"],
"media": ["{{ $json.image }}"]
}

Three logical nodes. Without a unified API the same workflow needs four separate platform nodes (or four HTTP Request nodes with hand-rolled OAuth refresh).

Conditional posting per platform

n8n’s Switch node plugs in cleanly:

[Webhook]
→ [Switch on type]
├─ "video" → [HTTP Request: Postproxy]
│ body = { "post": {...}, "profiles": ["tiktok","instagram","youtube"],
│ "media":[...],
│ "platforms": {
│ "tiktok": { "privacy_status": "PUBLIC_TO_EVERYONE" },
│ "instagram":{ "format": "reel" },
│ "youtube": { "privacy_status": "public" }
│ } }
├─ "image" → [HTTP Request: Postproxy]
│ body = { "post": {...}, "profiles": ["instagram","pinterest"],
│ "media":[...],
│ "platforms": {
│ "pinterest": {
│ "board_id": "987654321",
│ "destination_link": "{{$json.url}}"
│ }
│ } }
└─ "text" → [HTTP Request: Postproxy]
body = { "post": {...}, "profiles": ["twitter","linkedin","threads"] }

Same credential, three branches.

Status checks

Pair with a Wait + GET node, or use a Postproxy webhook → n8n Webhook trigger:

[HTTP Request: Postproxy create] → returns { id: "p_abc" }
→ [Wait 60 seconds]
→ [HTTP Request: GET /api/posts/{{ $json.id }}]
→ [If: status == "processed"]
├─ true → [Slack: post message "Published"]
└─ false → [Slack: "Failed: " + error]

The post-level status moves through processingprocessed (or scheduled for future posts). Per-platform statuses are inside platforms[].status (processing, published, failed).

A real workflow: AI-generated → cross-posted

Combining n8n’s OpenAI / Anthropic nodes with the Postproxy POST makes a content pipeline:

[Cron: every Monday 9am]
→ [HTTP: fetch this week's product changelog]
→ [Anthropic: summarize into 3 social posts]
→ [Loop: for each post]
→ [HTTP Request: Postproxy]
body = {
"post": { "body": "{{ $json.text }}" },
"profiles": ["twitter", "linkedin", "threads"]
}

A weekly content drop. If the team prefers explicit review, insert a Slack approval step before the Postproxy node and only fire on approved reactions.

For the longer end-to-end version of this pipeline, see Building an AI content pipeline from generation to publishing.

Self-hosted n8n vs cloud

The setup is the same on both. Self-hosted n8n can also pull POSTPROXY_API_KEY from env vars and reuse it across workflows.

Troubleshooting

IssueFix
401 Unauthorized on first runAPI key copied with whitespace, or wrong header (Authorization: Bearer ...)
Post stuck in processingLong video; check Postproxy dashboard for per-platform state
Profile not found for XThe platform isn’t connected to your Postproxy account, or you passed an unrecognised network name
Missing privacy_status (TikTok/YouTube)TikTok and YouTube require privacy_status — set it in platforms

Why n8n is a good fit

n8n’s strength is gluing things together with explicit, version-controllable workflows. Social media publishing has a lot of “happy path” and a lot of “what if a platform 429s.” n8n makes both visible. Putting the publish step behind one HTTP Request node — Postproxy — means the workflow stays readable.

Deeper reading: n8n tutorial workflow for a step-by-step build, and why n8n first on why we ship the n8n integration before others.

Ready to get started?

Start with our free plan and scale as your needs grow. No credit card required.