· 5 min read · postpeg team
Automate social posting with n8n, Make or Zapier
Publish to X, LinkedIn, Instagram and more from n8n, Make or Zapier with their built-in HTTP steps: exact settings, JSON escaping, idempotency and failure alerts.
Most "post this everywhere" automations are the same three steps: something happens (a blog post goes live, a row lands in a sheet, a product is added), you turn it into text and maybe an image, and you publish it to a handful of accounts. The trigger side is easy in n8n, Make and Zapier. The publishing side is where it gets tedious, because every network has its own app, its own login and its own rules.
This guide wires the publishing side to one HTTP request instead. It works today in all three tools, with no custom app to install, and the same request reaches X, LinkedIn, Instagram, Facebook, TikTok, YouTube, Threads, Pinterest, Bluesky and Google Business.
The one request every workflow sends
Whatever tool you use, the step you're building is this:
POST https://api.postpeg.com/v1/posts
Authorization: Bearer pp_live_your_key
Content-Type: application/json
Idempotency-Key: rss-8f3a1c
{
"account_ids": ["acc_mfz1x0k27d4q8vbn3c5s0a1p9e", "acc_mfz1y4r9h2c6t0wqk8e3m7ld5f"],
"content": "New on the blog: how we cut build times in half https://example.com/blog/builds"
}Three fields matter:
account_idsare the accounts to post to. Get them once withGET /v1/accountsand paste them in; they don't change, even when an account is reconnected.contentis the text, written once. postpeg checks it against every target network's limit before anything is sent, and if any network would refuse it, the whole request comes back as400with every problem listed, so nothing goes out half-done.Idempotency-Keyis a header you build from something unique to the item. Workflow tools retry steps, and a retried request with the same key returns the original post instead of publishing twice.
Add "scheduled_at": "2026-10-01T09:00:00Z" to schedule instead of publishing now, and "media": [{ "url": "https://…", "type": "image" }] for images or video. Instagram, TikTok, YouTube and Pinterest need media.
The response is the post with one target per account. Publishing runs in the background and usually finishes within seconds; GET /v1/posts/{id} then shows each target as published with its link, or failed with the reason.
n8n: the HTTP Request node
n8n's HTTP Request node is a core node, so it's in every edition, including self-hosted. Set it up like this:
| Field | Value |
|---|---|
| Method | POST |
| URL | https://api.postpeg.com/v1/posts |
| Authentication | Generic Credential Type → Header Auth, name Authorization, value Bearer pp_live_… |
| Send Headers | Idempotency-Key = rss-{{ $json.guid }} |
| Send Body | JSON, Using JSON |
For the body, don't put quotes around mapped text. Let JSON.stringify add them, so a title with a quote mark or a line break can't break the JSON:
{
"account_ids": ["acc_mfz1x0k27d4q8vbn3c5s0a1p9e", "acc_mfz1y4r9h2c6t0wqk8e3m7ld5f"],
"content": {{ JSON.stringify($json.title + " " + $json.link) }}
}The same node can also paste in a curl command with Import cURL, and it can page through lists by itself: list endpoints return data and next_cursor, so use pagination mode "Update a Parameter in Each Request" with a cursor query parameter set from $response.body.next_cursor, and stop when it's empty.
Make: HTTP → Make a request
Make's HTTP app has a Make a request module. Fill in the URL and method, add Authorization and Idempotency-Key under Headers, set the body content type to application/json, and turn on Parse response so you can map the returned post id.
The catch in Make is the same as in n8n: mapping raw text into a JSON body works until the first double quote. Put a JSON → Transform to JSON module in front with the text you want to post; its output is already a quoted, escaped JSON string, so you map it in without quotes:
{
"account_ids": ["acc_mfz1x0k27d4q8vbn3c5s0a1p9e", "acc_mfz1y4r9h2c6t0wqk8e3m7ld5f"],
"content": {{2.json}}
}A list request returns one page (up to 100 posts). For most workflows that's all you need; for more, request again with cursor set to the previous next_cursor.
Zapier: Webhooks by Zapier
In Zapier, use Webhooks by Zapier with the Custom Request action, which lets you send raw JSON. Set Method to POST, paste the URL, put the JSON body in Data, and add three headers: Authorization, Content-Type: application/json and an Idempotency-Key mapped from the trigger item's ID. Webhooks by Zapier isn't on Zapier's Free plan; it needs Professional, Team or Enterprise.
Custom Request sends Data exactly as typed, so the escaping rule applies here too. If your text can contain double quotes or line breaks, build the body in a Code by Zapier step with JSON.stringify and map that into Data.
Three workflows worth building
Publish every new RSS item to X and LinkedIn. An RSS trigger (n8n's RSS Feed Trigger, Make's Watch RSS feed items, or RSS by Zapier) feeds the request above, with the item's guid as the idempotency key. Two steps, and your blog announces itself.
Schedule a Google Sheets row as a post. Give the sheet columns for text, an image URL and a date in ISO 8601. When a row is added, send it with scheduled_at from the date column, then write the returned post id back to the row. Someone who never opens your dashboard can now plan a month of posts in a spreadsheet, and cancelling one is DELETE /v1/posts/{id}.
Alert Slack when a post fails. Don't re-post failures from the workflow: postpeg already retries a network that has a bad minute, up to five attempts. What a person needs to know is when it gives up. Poll GET /v1/posts?status=failed every 15 minutes and send each new one to Slack with the target's error. In Zapier, the Webhooks Retrieve Poll trigger does the polling and skips posts it has already seen, keyed on id; set its Key to data. In n8n, a Remove Duplicates node does the same job between runs. Poll status=partially_published too, to catch posts that went out on some accounts but not others.
Limits and a word on testing
Each API key can make 120 requests a minute, and at most 30 of them can be writes such as publishing or replying. A loop that goes faster gets 429 rate_limited with a Retry-After header: wait that long and send the same request again, with the same idempotency key. Workflows that post a few times a day will never notice. The rate limits are all listed in the docs.
One thing to know before you test: pp_test_ keys currently publish for real, just like live keys. Point your first run at an account you own, or schedule the post a day ahead and cancel it.
Native apps and AI agents
postpeg apps for n8n, Make and Zapier are built and waiting to be published. When they ship, you'll pick "postpeg" from a list instead of filling in an HTTP step. Everything above keeps working, so there's no reason to wait. If you'd rather have an assistant do the posting, the MCP server connects Claude, Cursor or VS Code to the same API, and asks before anything goes out.
Step-by-step setup for each tool, with every field, is in the integration guides.