---
title: "n8n WordPress Trigger: Polling vs Webhooks"
description: "There is no n8n WordPress trigger node, so most workflows poll. Where that works, the events it is structurally blind to, and the WP-Cron objection answered."
url: "https://wpwebhooks.org/blog/n8n-wordpress-trigger/"
date: "2026-09-08"
---

# n8n WordPress Trigger: Polling vs Webhooks

**TL;DR:** n8n has no WordPress trigger node, so most people poll. That is the right default for posts and orders — and it is structurally blind to most WordPress events.

-   The official **WordPress node is actions-only** — create, update, retrieve. It does not listen.
-   Polling works where the REST API exposes a **queryable, date-filterable list**. Posts qualify. Most things do not.
-   `/wp/v2/users` has **no date filter at all**. You can find new users; you cannot detect an updated one.
-   Polling reads **state**. A value that changes and changes back between two polls never happened.
-   The "webhooks don't fire because WP-Cron needs traffic" objection is real, and has four separate fixes — one of which needs no cron at all.

/ Objection

## Why do n8n users poll WordPress instead of receiving webhooks?

Because the platform pushes them that way, and because the usual alternative has a bad reputation.

n8n's official [WordPress node](https://n8n.io/integrations/wordpress/) is an action node. It creates posts, updates posts, retrieves posts and users. There is no WordPress trigger node — nothing in the box listens for something happening on your site. So the natural shape of a WordPress workflow in n8n is a Schedule Trigger followed by an HTTP Request or the WordPress node, asking "anything new since last time?"

The second reason is the one that comes up in every thread: WordPress webhooks are widely believed to be unreliable, because WP-Cron only runs when somebody visits the site. On a quiet site a queued delivery can sit for hours. That belief is _correct about the default_, and we will deal with it properly further down — but it is worth separating the two questions. "Is push reliable here?" is a configuration question with a known answer. "Can polling see this event at all?" is a structural one, and it does not have an answer.

Credit where it is due: for the two cases people usually build first, polling is genuinely the better default. It needs nothing installed on the WordPress side, which matters enormously when the site belongs to a client who will not let you add a plugin. It is stateless and self-healing — if n8n is down for an hour, the next poll simply picks up a wider window. And it backfills: a webhook only ever fires forward, so a workflow built today knows nothing about yesterday.

| WordPress event | Pollable? | Why |
| --- | --- | --- |
| New post published | Yes | /wp/v2/posts supports after and modified\_after |
| Post edited | Yes | orderby=modified plus modified\_after |
| New WooCommerce order | Yes | /wc/v3/orders exposes date filters |
| New user registered | Partly | orderby=registered\_date only — no date filter |
| User profile updated | No | no modified field, no date filter, no ordering |
| Contact Form 7 submission | No | nothing is stored without an add-on |
| Comment approved | No | status transition leaves no queryable trace |
| Any custom do\_action | No | no endpoint exists to poll |

/ Limits

## What can polling not see?

Polling is a query against a list. It works when three things are true at once: the thing you care about is stored, that store has a REST endpoint, and that endpoint can be filtered or ordered by a date that changes when the thing happens. Posts satisfy all three, which is why every popular n8n WordPress template is built on them.

Users do not. The List Users endpoint accepts `context`, `page`, `per_page`, `search`, `exclude`, `include`, `offset`, `order`, `orderby`, `slug`, `roles`, `capabilities`, `who` and `has_published_posts`. There is no `after`, no `modified_after`, and the permitted `orderby` values stop at `registered_date`. You can therefore find users who registered since your last run, and you have no mechanism whatsoever for finding a user whose profile changed:

n8n — the poll that cannot be written

```
// Works: new users since the last run.
GET /wp-json/wp/v2/users?orderby=registered_date&order=desc&per_page=20
// then discard everything older than $lastRun in a Code node

// Does not exist: users whose profile changed since the last run.
GET /wp-json/wp/v2/users?modified_after=2026-09-08T00:00:00
// ^ modified_after is silently ignored. You get page 1 of all users.

// The only remaining option is a full-table diff, every run:
//   fetch every user, hash each record, compare against a stored hash.
//   10,000 users x every 5 minutes = 2.88M records/day to notice one edit.
```

That last line is the honest cost of forcing a poll onto an event that was never designed to be polled. It is not that it is impossible — it is that the workaround is a full-table diff on a schedule, and it scales with the size of your site rather than with the number of things that actually happened.

The deeper problem is that **polling reads state, not events**. A poll tells you what is true now. It cannot tell you what happened in between. If a post is published and then unpublished inside your five-minute window, your workflow never sees it. If an order moves from processing to completed to refunded between two runs, you observe one transition and miss two. For an audit trail, a notification, or anything where the transition _is_ the business event, that gap is the whole problem.

And then there is the class of events that leaves no trace at all. Contact Form 7 does not store submissions — without an add-on such as Flamingo, the data exists only for the duration of the request that carried it. There is nothing to poll, at any interval, ever. The same is true of every custom `do_action` in every plugin on the site: those are the events that make WordPress extensible, and none of them has an endpoint.

![Cyberpunk illustration: in a dim service corridor an augmented operator hauls a hooded scanning head around on a geared mast, one boot braced against its base and her face sealed into its eyepiece, so the single narrow arc of light it throws — falling on one raised shutter with a lit interior — is the only thing she can see; further down the rank behind her turned back, three shutters have already come down, orange light still draining from their seams.](https://wpwebhooks.org/blog/n8n-wordpress-trigger/og_image.jpg)

> Polling answers "what is true now?". A webhook answers "what just happened?". Most WordPress events are the second question, and only the first one has an endpoint. — the line between the two approaches

/ Cron

## But don't WordPress webhooks fail because WP-Cron needs traffic?

This is the strongest argument against push and it deserves a straight answer rather than a defence. [WP-Cron is not a scheduler](https://wpwebhooks.org/blog/async-webhooks-wordpress-wp-cron-not-enough/) — it is a task list checked during page loads. If a plugin accepts an event, queues it, and waits for WP-Cron to drain the queue, then on a site with no visitors nothing is drained. The event is not lost, but it is not delivered either, and "delivered eventually, when someone happens to browse the site" is not a property you can build an automation on.

There are four ways out of it, and they are worth knowing in order of how little work they take:

-   **Send synchronously.** The delivery fires inline, inside the request that triggered it, and never touches cron at all. It costs a little latency on that one request and it works on any site from the moment it is switched on. This is the correct default on a low-traffic site, and it is exactly what the objection is asking for.
-   **Let Action Scheduler take the queue.** If Action Scheduler is present — and it is on every WooCommerce site, because WooCommerce ships it — a queue can be handed to it instead of WP-Cron, which gives persistent job tracking and far better behaviour under load. On a WooCommerce store the problem tends not to arise in the first place.
-   **Point a real cron at it.** A token-authenticated REST endpoint that a system crontab or a free external pinger hits on a fixed schedule turns "when someone visits" into "every sixty seconds". [External cron services](https://wpwebhooks.org/blog/wordpress-external-cron-services/) covers the free options.
-   **Use a managed pinger.** The same thing without a crontab, for people who do not have shell access to the server.

The distinction that matters for an n8n user evaluating this: the failure mode above is a property of _queued delivery on an idle site_, not of webhooks. Synchronous delivery has no cron in the path. Once that is understood, the reliability question stops being "can WordPress push?" and becomes the ordinary question you would ask of any sender — does it retry, can you see what it sent, and can you replay it when the receiving workflow had a bug?

/ Choosing

## Which should an n8n workflow actually use?

Both, in different places — and on the push side it matters a great deal _what_ is doing the pushing. A hand-rolled `wp_remote_post` inside a hook is a webhook in the same sense that a `curl` in a loop is a delivery system: it works until the receiving end is down. So the honest comparison has three columns, not two.

| Concern | Polling from n8n | Raw `do_action` + `wp_remote_post` | Webhook Actions |
| --- | --- | --- | --- |
| Setup on the WordPress side | Nothing at all — works on sites you do not control | A snippet per event, maintained by you | Install once, then wire events up in wp-admin |
| Events it can observe | Only what has a date-filterable REST endpoint | Any `do_action` — one snippet each | Any `do_action`, including custom plugin events |
| Transitions and one-off events | Missed if they resolve between two polls | Delivered when they happen | Delivered when they happen |
| Latency | Half the poll interval on average | Immediate — inside the request | Immediate synchronously, or seconds when queued |
| Load when nothing happens | Every interval, all day, forever | None | None |
| Delivery on an idle, low-traffic site | Unaffected — n8n does the polling | Inline works; a WP-Cron queue never drains | Synchronous mode, or Action Scheduler / real cron |
| Retrying a failed delivery | Not needed — the next poll re-reads | None — `wp_remote_post` fires once | Automatic on 5xx and 429, exponential backoff, 5 attempts |
| Recovering from a broken workflow | Re-run against an earlier window | The payload is gone | Every request and response logged; replay the original event |
| Backfilling history from before you set it up | Widen the date window and re-run | Not possible — fires forward only | Not possible — fires forward only |

Read the last three rows together and the practical rule falls out. Polling recovers by re-querying, so its resilience is free. A webhook fires once, so _everything_ depends on whether the sender kept the payload — which is why the middle column is not a cheaper version of the third one, it is a different reliability class. A sender that fires and forgets genuinely is worse than a poll. A sender that stores every payload, retries on `5xx` and `429`, and lets you re-send the original event after you fix the workflow is strictly better, because it also sees the events polling cannot reach.

So: poll for posts and orders on sites you do not control, and for backfilling anything that happened before the integration existed. Push for form submissions, user changes, status transitions and anything custom — and use something that keeps a delivery log, rather than a snippet that throws the payload away the moment n8n returns a 500.

try\_it

Seeing it run beats reading about it. The live preview boots a throwaway WordPress with Webhook Actions already installed and demo deliveries sitting in the log — no signup, nothing left on your machine afterwards.

[Try the live preview →](https://playground.wordpress.net/?blueprint-url=https://wpwebhooks.org/blueprint.json) [Install plugin](https://downloads.wordpress.org/plugin/flowsystems-webhook-actions.zip)

/Footnotes

¹ WordPress node operations, [n8n integrations directory](https://n8n.io/integrations/wordpress/).

² List Users query parameters and permitted orderby values, [WordPress REST API Handbook](https://developer.wordpress.org/rest-api/reference/users/).

³ Posts date filters — after, before, modified\_after, modified\_before, [WordPress REST API Handbook](https://developer.wordpress.org/rest-api/reference/posts/).

⁴ WP-Cron is triggered on page load, [WordPress Plugin Handbook](https://developer.wordpress.org/plugins/cron/).

## Structured data

```json
{"@context":"https://schema.org","@type":"Article","headline":"n8n WordPress Trigger: Polling vs Webhooks","description":"There is no n8n WordPress trigger node, so most workflows poll. Where that works, the events it is structurally blind to, and the WP-Cron objection answered.","datePublished":"2026-09-08","dateModified":"2026-09-08","author":{"@type":"Person","name":"Mateusz Skorupa","url":"https://wpwebhooks.org/about/"},"publisher":{"@type":"Organization","name":"WP Webhooks","url":"https://wpwebhooks.org"},"url":"https://wpwebhooks.org/blog/n8n-wordpress-trigger/","image":{"@type":"ImageObject","url":"https://wpwebhooks.org/blog/n8n-wordpress-trigger/og_image.jpg","width":1200,"height":630,"caption":"Cyberpunk illustration: in a dim service corridor an augmented operator hauls a hooded scanning head around on a geared mast, one boot braced against its base and her face sealed into its eyepiece, so the single narrow arc of light it throws — falling on one raised shutter with a lit interior — is the only thing she can see; further down the rank behind her turned back, three shutters have already come down, orange light still draining from their seams."},"keywords":["n8n wordpress trigger","n8n wordpress webhook","trigger n8n from wordpress","n8n wordpress integration","wordpress webhook n8n"]}

{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"WP Webhooks","item":"https://wpwebhooks.org/"},{"@type":"ListItem","position":2,"name":"Blog","item":"https://wpwebhooks.org/blog/"},{"@type":"ListItem","position":3,"name":"n8n WordPress Trigger: Polling vs Webhooks","item":"https://wpwebhooks.org/blog/n8n-wordpress-trigger/"}]}

{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"Does n8n have a WordPress trigger node?","acceptedAnswer":{"@type":"Answer","text":"No. The official WordPress node in n8n is an action node — it creates, updates and retrieves posts, pages and users. Nothing in n8n listens for WordPress events, so workflows either poll on a Schedule Trigger or receive a webhook sent by something installed on the WordPress side."}},{"@type":"Question","name":"Can I poll WordPress from n8n instead of using webhooks?","acceptedAnswer":{"@type":"Answer","text":"Yes, and for posts and WooCommerce orders it is a reasonable default. The /wp/v2/posts endpoint supports after, before, modified_after and modified_before, and orderby=modified, so a Schedule Trigger plus an HTTP Request reliably finds what changed since the last run without installing anything on the site."}},{"@type":"Question","name":"Which WordPress events cannot be detected by polling?","acceptedAnswer":{"@type":"Answer","text":"Anything without a date-filterable REST endpoint. User profile updates cannot be polled at all — /wp/v2/users has no after or modified_after parameter and its orderby values stop at registered_date. Contact Form 7 submissions are not stored without an add-on, so nothing exists to query, and custom do_action events have no endpoint whatsoever."}},{"@type":"Question","name":"Why do WordPress webhooks not fire on low-traffic sites?","acceptedAnswer":{"@type":"Answer","text":"Because a queued delivery usually waits for WP-Cron, which only runs when someone loads a page. On an idle site the queue is never drained. The fix is either synchronous delivery, which fires inline during the triggering request and needs no cron at all, or handing the queue to Action Scheduler, a system crontab or an external pinger."}},{"@type":"Question","name":"Is polling or a webhook better for triggering n8n from WordPress?","acceptedAnswer":{"@type":"Answer","text":"They fail in opposite directions, so it depends on the event. Poll for posts and orders on sites you do not control, since polling needs nothing installed and can backfill history. Push for form submissions, user changes, status transitions and custom hooks, since those either leave no queryable record or resolve between two polls."}}]}
```
