You publish a blog post. Your n8n WordPress social media automation workflow shares it on Facebook, then tries LinkedIn.

Facebook works. LinkedIn fails.
So you run the workflow again.
Now Facebook has two copies of the same post, and LinkedIn might still have none.
This is a common problem with social media automation. The workflow knows something failed, but it doesn’t remember which parts already worked.
The fix starts with a simple rule: track each platform separately.
Quick Answer for n8n WordPress social media automation
To prevent duplicate posts in n8n WordPress social media automation, keep a saved record for each article and social account. Skip posts that already succeeded and retry only failed channels. If a request times out, check whether the platform published it before trying again. Otherwise, your retry could create another copy.
About this guide: This is a proposed setup based on official documentation. Operant Solo has not completed testing of this exact workflow. Check it with test accounts before letting it publish without your review.
Why does n8n WordPress social media automation publish the same article twice?
There are several ways it can happen.
- You might receive the same webhook twice.
- Two scheduled runs might pick up the same article.
- Or you might rerun a failed workflow without checking which platforms already received the post.
WordPress can also trigger the workflow when you edit an article. Its publish_post hook can run when a post is first published and when an already-published post is updated. Without a status check, fixing a typo could start another round of social posts. WordPress documentation.
There’s another problem that is harder to spot: a social platform might accept your post, but n8n never receives the reply. Your workflow shows a timeout. The post is already live. Trying again could publish it twice.
Give every platform its own record
A single “posted” label for an article isn’t enough. Suppose Facebook works and LinkedIn fails. Should the article be marked as posted or failed? Both labels leave out part of the story.
Instead, create a separate record for each destination: WordPress site + article ID + platform + account ID
For example: operantsolo + 2233 + facebook + page_123
The account ID matters. Posting to two Facebook Pages means you need two records.
Your record should answer these questions:
| Information | Why you need it |
|---|---|
| Article ID | Which WordPress post is this? |
| Platform and account | Where should it be shared? |
| Status | Is it waiting, being sent, published or needing attention? |
| Approved caption | What exactly should be published? |
| Number of attempts | How many times have you tried? |
| Social post ID | What did the platform create? |
| Next retry time | When can the workflow try again? |
| Last update time | Has this task been stuck for too long? |
Keep passwords and API tokens in n8n credentials. Don’t put them in the publishing record.
Where should you save these records?
The right choice depends on how much work your workflow handles.
| Method | Keeps history between runs | Handles overlapping runs | Tracks each platform | Main drawback |
|---|---|---|---|---|
| Filter recent articles | No | No | No | The same article can appear in several runs |
| n8n workflow static data | Under documented conditions | Don’t assume it does | With custom logic | Has testing and reliability limits |
| Google Sheets | Yes | Needs extra controls | Yes | Two runs can read the same row before either updates it |
| Postgres database | Yes | Can use database rules | Yes | Requires more setup |
n8n says workflow static data is experimental. It isn’t saved during manual testing, and it may be unreliable when workflows run very frequently. Changes are saved when an execution succeeds. n8n documentation.
For this design, use Postgres. It lets you make a task unique and claim it in one database operation. That matters because two runs can otherwise check the same record, both see “not posted,” and both publish.
Build the workflow step by step
The main flow looks like this:
WordPress event → Fetch article → Create captions → Get approval → Save one task per platform → Claim a task → Publish → Save the result
A separate recovery flow checks failed or stuck tasks. You may want a human-in-the-loop approach for handling approvals.
1. Trigger n8n when an article is published
Send the WordPress article ID to an authenticated n8n webhook: { "post_id": 2233 }
Use Header Auth on the Webhook node. Store the shared secret securely on both sides. On the WordPress side, check that:
- The content type is a post.
- The new status is publish.
- The old status was not publish.
This stops ordinary edits from starting another publishing request. It won’t cover every case. Someone could unpublish an article and publish it again. Your saved records must still catch repeated requests.
Use a fixed, trusted WordPress site URL in n8n. Don’t let anyone send an arbitrary URL for the workflow to fetch.
2. Fetch the article from WordPress
Use an HTTP Request node to get the article:GET https://YOUR-SITE/wp-json/wp/v2/posts/2233
Check that the article is published. Then collect its title, link, excerpt and image details.
Public posts may be available without logging in. Sites that restrict access need suitable authentication. WordPress Posts API.
Clean up HTML before using the excerpt in a caption. If you use scheduled polling instead of a webhook, handle all result pages. Allow a small overlap between polling windows so you don’t miss articles. Use your saved records to remove repeats.
3. Create captions and approve them
AI can help turn an article into captions for different platforms. But check the output before sending it:
- Does it contain the correct article link?
- Is the text suitable for the platform?
- Is the required image available?
- Did the AI add a claim that the article doesn’t support?
For human approval, save the exact caption and image details the reviewer saw. If you change the caption afterward, ask for approval again. Retries should use the same approved content. Generating a new caption during every retry makes it harder to know what was reviewed and what went live. If approval expires, stop and flag the task for attention.
4. Save one task for each social account
Create a publishing record for every selected platform and account. Make the combination of site, article, platform and account unique in your database. A repeated webhook should find the existing task rather than create another one. It should also leave published records alone.
For example:
| Article | Platform | Status |
|---|---|---|
| 2233 | Facebook Page | Published |
| 2233 | LinkedIn profile | Waiting to retry |
| 2233 | X account | Blocked—needs attention |
Use the Postgres node’s Query Parameters when passing values into SQL. Avoid joining incoming text directly into a query. n8n supports parameter placeholders such as $1 and $2. n8n Postgres reference.
5. Claim a task before publishing
Before sending a post, change an eligible task from queued or retryable to sending. Do this in one database operation. Only the run that successfully changes the record should continue to the publishing node. If another run already claimed it, stop that branch.
Give each attempt a unique ID and save it with the record. When the response arrives, use that ID to update the correct attempt. Don’t automatically resend a task just because it has been marked sending for a long time. The platform may already have received it.
6. Save what actually happened
For HTTP Request nodes, Include Response Headers and Status helps you inspect the reply. Never Error lets you route non-success HTTP responses yourself. Network failures still need their own error path. n8n HTTP reference.
Handle the outcomes separately:
| Result | What to do |
|---|---|
| Platform confirms publication | Save its post ID and mark the task published |
| Platform accepts a background job | Wait for confirmation that publishing finished |
| Platform rejects the request but allows retrying | Schedule a limited retry |
| Credentials or content are invalid | Stop and fix the problem |
| Request times out or the result is unclear | Mark it unknown and investigate |
A timeout doesn’t prove the post failed. The same caution applies to server errors. Check the provider’s behavior before deciding a retry is safe. Some APIs support a request key that helps them recognize repeated calls. Use that feature where documented. Don’t assume every platform supports it.
7. Retry only the channel that needs it
Once Facebook is confirmed as published, leave it alone. If LinkedIn has a known retryable failure, retry LinkedIn using the original approved caption.
An example retry schedule could be:
- First retry: after 30 seconds
- Second retry: after 2 minutes
- Third retry: after 10 minutes
These are example settings, not platform limits. Follow the provider’s instructions, including any Retry-After header.
For unknown results, check the platform through a supported lookup or status API. If you still cannot establish what happened, ask someone to review it. A database helps control your own runs. It cannot guarantee that an external platform will publish exactly once when responses are lost.
Test the awkward cases
A successful first run tells you the connections work. It doesn’t prove recovery works. Before enabling unattended publishing, test these cases:
| Test | What should happen |
|---|---|
| Send the same webhook twice | No second publication |
| Edit an already-published article | No unintended repost |
| Let Facebook work and another channel fail | Facebook stays untouched |
| Rerun the workflow manually | Confirmed posts are skipped |
| Start two runs together | Only one claims each task |
| Accept a post, then simulate a timeout | No blind retry |
| Stop the workflow before saving a successful result | The stuck record goes to review |
| Change a caption after approval | The old approval is no longer accepted |
Use test accounts or a mock API where possible. Keep the inputs, logs and social post IDs. Record your n8n version too, so someone else can reproduce the setup.
What will it cost?
The workflow can involve four separate costs:
- n8n hosting or a subscription.
- A database.
- AI caption generation.
- Social API access or a publishing service.
A free template doesn’t mean the whole setup is free. Check current account requirements, API access, permissions and media rules for each platform. Start with one channel and add more after the basic flow works.
If n8n Cloud fits your needs, you can use n8n Cloud. Operant Solo may earn a commission at no extra cost to you. Self-hosting is another option, but you handle its maintenance. Check out our n8n review for more details.
Who is this for?
This setup fits WordPress publishers and small agencies that want to see which posts worked and recover from failures without repeating successful channels. It is useful when you already use n8n and are comfortable maintaining credentials and a database.
Who should avoid it?
If you mainly want a simple posting calendar, a dedicated social scheduler may be easier. This workflow needs maintenance. Importing a JSON file won’t remove API restrictions, expired credentials or failed requests.
Frequently Asked Questions
Will the Remove Duplicates node stop every duplicate post?
No. It can help filter repeated input, but it doesn’t settle whether a platform published a post before a timeout. You still need saved results for each destination and a recovery plan.
Can I use Google Sheets instead of Postgres?
Yes, for a simpler setup with carefully controlled execution. Ordinary read-and-update steps can clash when runs overlap, so you need extra controls and testing.
Should I rerun the whole workflow when one platform fails?
Only if every publishing branch first checks its saved status. Successful platforms must be skipped; eligible failed channels can then retry with the approved content.
Can I guarantee that a post will never appear twice?
Not across every API and failure case. You can prevent many duplicate requests, but lost responses may still require checking the platform before trying again.
Want more practical n8n guides? Join the Operant Solo newsletter for workflow breakdowns, troubleshooting and future download announcements. This workflow has not yet been released as a tested downloadable product.
