Zapier, n8n, Make, and webhook examples
These examples show both Nuwtonic automation flows:
- Publish a generated article from an actionable
content.generatedevent. - Update an existing page from a
fix.applyevent containing content or SEO fixes.
Start with the connection and event contract guide. Build and test the article and fix flows separately.
Do not send every event to a publish action. The same URL also receives tests and completion notifications. Always route by the top-level
eventfield before changing a website.
1. Routing required in every tool
Create these routes or branches:
- Article:
eventequalscontent.generated;data.result.title,content, orcontent_htmlexists; anddata.result.published_countdoes not exist. - Fix:
eventequalsfix.apply;data.target_urlexists; anddata.fixesis a non-empty list. - Publish summary:
eventequalscontent.generatedanddata.result.published_countexists. Log or ignore it. - Fix completion:
eventequalsfix.generated. Log or ignore it. - Connection test:
eventequalstest. Return success without publishing or updating anything.
Store the top-level event id. If the same ID arrives again, acknowledge it without repeating the action.
Complete synchronous webhook work within 30 seconds. If you return 202, persist the operation safely before responding; Nuwtonic has no later endpoint for your workflow to report its final result.
What a fix workflow must do
A fix.apply request is not a finished article. It is a set of instructions for an existing page:
- Find exactly one CMS record using
data.target_url. - Load the latest editable content and metadata.
- Inspect each item in
data.fixes. - Validate
current_valuebefore replacing content. - Apply only fix types supported by the destination.
- Save the updated page.
- Return the destination record ID and final URL.
Do not create a new post for fix.apply.
2. WordPress prerequisites
For the simplest automatic WordPress fixes, use Nuwtonic's native WordPress integration. Use the webhook approach only when you need a custom automation.
A webhook automation that updates WordPress needs:
- the WordPress site URL;
- credentials with permission to read and update posts or pages;
- a way to resolve
data.target_urlto the correct WordPress post or page ID; - access to every field you want to update.
The core WordPress REST API can update post titles and content. Yoast, Rank Math, other SEO metadata, JSON-LD, and some image fields may not be exposed by default. Expose those fields safely through your plugin or a protected custom endpoint before enabling the corresponding fix types.
For a target such as:
https://example.com/blog/best-ai-seo-tools
the slug is usually best-ai-seo-tools. A WordPress lookup can use:
GET https://example.com/wp-json/wp/v2/posts?slug=best-ai-seo-tools&context=edit
If it is a page, use /wp-json/wp/v2/pages instead. Do not guess between multiple matches.
3. Zapier example: publish an article
Trigger and routes
- Create a Zap.
- Choose Webhooks by Zapier → Catch Hook.
- Copy the Catch Hook URL into Nuwtonic and enable the webhook.
- Publish one low-risk test article so Zapier receives a real article payload. Send Test Event is not enough because it sends only
event: test. - Add Paths by Zapier.
- Create an Article path with these conditions:
- Event exactly matches
content.generated. - Data Result Title exists, or Data Result Content exists.
- Data Result Published Count does not exist.
- Event exactly matches
Zapier may display data.result.title as Data Result Title. Select the field from the trigger output instead of typing the label manually.
WordPress action
Add WordPress → Create Post and map:
- Title: Data Result Title
- Content: Data Result Content HTML; fall back to Data Result Content
- Slug: Data Result Slug
- Status: Data Result Status
If the WordPress action does not expose a required field, use Webhooks by Zapier → Custom Request to call a protected CMS endpoint.
Verify
- Run the path with the test article.
- Confirm that exactly one post was created.
- Confirm title, HTML, slug, status, and final URL.
- Turn the Zap on.
Zapier Catch Hook acknowledges delivery before later actions finish. Check Zap History and enable error alerts; Nuwtonic cannot see a later Zapier action failure.
4. Zapier example: apply a content fix
This example applies an exact content_replacement to an existing WordPress post.
Fix path
In the same Zap, create a Fix path:
- Event exactly matches
fix.apply. - Data Target URL exists.
- Data Fixes exists.
Then:
- Use Code by Zapier or Formatter to extract the last path segment from Data Target URL as the slug.
- Use the WordPress app if it supports finding a post by URL or slug. Otherwise use Webhooks by Zapier to call the WordPress REST API lookup shown above.
- Confirm that the lookup returns exactly one post or page.
- Use Looping by Zapier only if every fix is handled safely. For complex fixes, send the complete
data.fixeslist to one protected custom endpoint instead. - For
content_replacement, compare the latest editable content withcurrent_value. - If it matches exactly once, replace it with
suggested_value. - Update that post or page. Do not create a new post.
- If it is missing or appears more than once, stop and alert the user instead of guessing.
Other fix types in Zapier
meta: send it to a CMS/SEO metadata field or custom endpoint. Never paste<title>or<meta>into the visible post body.schema: send validated JSON-LD to a schema/head field or custom endpoint.content_addition: add it only at the explicitly identified location and check for duplicates.image_alt: update the matching media record, not the post title or body.faq: add visible FAQ HTML and any separate FAQPage schema without duplicating either.
Standard Zapier WordPress actions may not support these advanced fields. If the required field is unavailable, use a protected custom API or the native Nuwtonic WordPress integration.
5. n8n example: publish an article
Use this node order:
Webhook → Switch → WordPress/HTTP Request → Respond to Webhook
Webhook node
- Set HTTP Method to
POST. - Set Respond to Using Respond to Webhook Node.
- Activate the workflow.
- Copy the Production URL into Nuwtonic. Do not save the temporary Test URL as the permanent connection.
In n8n, the received Nuwtonic payload is normally under body, so use:
{{ $json.body.event }}
{{ $json.body.data.result.title }}
{{ $json.body.data.result.content_html }}
If your n8n version exposes the JSON body at the root, use $json.event and $json.data instead. Inspect the Webhook node output once before mapping fields.
Switch node
Create an article output where:
{{ $json.body.event === "content.generated"
&& $json.body.data?.result?.published_count === undefined
&& !!($json.body.data?.result?.title
|| $json.body.data?.result?.content
|| $json.body.data?.result?.content_html) }}
Create separate outputs for fix.apply, fix.generated, test, and the publish summary.
End every test, summary, or unsupported-event output with Respond to Webhook status 200 and no CMS action.
WordPress or HTTP Request node
Map:
Title = {{ $json.body.data.result.title }}
Content = {{ $json.body.data.result.content_html || $json.body.data.result.content }}
Slug = {{ $json.body.data.result.slug }}
Status = {{ $json.body.data.result.status }}
After the CMS confirms the publish, use Respond to Webhook:
{
"id": "{{$json.id}}",
"link": "{{$json.link}}"
}
Map id and link from the destination node's actual output.
6. n8n example: apply content fixes
Use this node order:
Webhook → Switch(fix.apply) → Prepare Target → Load CMS Page
→ Apply Safe Fixes → Update CMS Page → Respond to Webhook
Prepare Target Code node
Name the Webhook node Nuwtonic Webhook, then use:
const payload = $("Nuwtonic Webhook").first().json.body
?? $("Nuwtonic Webhook").first().json;
const target = new URL(payload.data.target_url);
const slug = target.pathname.split("/").filter(Boolean).pop();
if (!slug || !Array.isArray(payload.data.fixes) || payload.data.fixes.length === 0) {
throw new Error("fix.apply is missing target_url or data.fixes");
}
return [{
json: {
eventId: payload.id,
targetUrl: payload.data.target_url,
slug,
fixes: payload.data.fixes
}
}];
Load CMS Page node
Use a WordPress node or authenticated HTTP Request:
GET https://example.com/wp-json/wp/v2/posts
Query: slug = {{ $json.slug }}
Query: context = edit
Use the pages endpoint when the target is a page. Stop if the result count is not exactly one.
Apply Safe Fixes Code node
This example handles exact content replacements. Name the previous node Prepare Target:
const source = $("Prepare Target").first().json;
const response = $input.first().json;
const record = Array.isArray(response) ? response[0] : response;
if (!record?.id) {
throw new Error("No editable CMS page matched data.target_url");
}
let content = record.content?.raw ?? record.content?.rendered ?? "";
const unsupported = source.fixes.filter(
(fix) => fix.type !== "content_replacement"
);
if (unsupported.length > 0) {
throw new Error(
`This example needs handlers for: ${[...new Set(unsupported.map((fix) => fix.type))].join(", ")}`
);
}
for (const fix of source.fixes) {
if (!fix.current_value || !fix.suggested_value) {
throw new Error(
"content_replacement is missing current_value or suggested_value"
);
}
const occurrences = content.split(fix.current_value).length - 1;
if (occurrences !== 1) {
throw new Error(`Expected one exact current_value match; found ${occurrences}`);
}
content = content.replace(fix.current_value, fix.suggested_value);
}
return [{
json: {
postId: record.id,
targetUrl: source.targetUrl,
content,
fixes: source.fixes
}
}];
Add explicit handlers or separate nodes for meta, schema, content_addition, image_alt, and FAQ fixes. Do not silently skip a type and report the whole operation as successful.
Update and response
Update:
POST https://example.com/wp-json/wp/v2/posts/{{ $json.postId }}
Body type: JSON
content field = {{ $json.content }}
After WordPress confirms the update, respond:
{
"id": "{{$json.id}}",
"link": "{{$json.link}}"
}
Return 404 when the target is missing, 409 when current content has changed, and 422 when the destination cannot support a fix type.
7. Make example: publish an article
Use this module order:
Custom webhook → Router → WordPress/HTTP → Webhook Response
- Add Webhooks → Custom webhook.
- Copy its URL into Nuwtonic.
- Select Run once, then publish a low-risk test article from Nuwtonic so Make learns the full article structure.
- Add a Router.
- Create an Article route with:
eventequalscontent.generated;data.result.titleor article body exists;data.result.published_countdoes not exist.
- Add WordPress → Create a Post, or an HTTP module for another CMS.
- Map title,
content_htmlorcontent, slug, and status. - Add Webhook Response after the destination module with status
200and the destination ID and URL.
Do not put Webhook Response before the CMS module; Nuwtonic would receive success before the update is confirmed.
Add a 200 Webhook Response to the test and notification routes without adding a CMS action.
8. Make example: apply content fixes
Create a Fix route where:
eventequalsfix.apply;data.target_urlexists;data.fixesis not empty.
Then:
- Extract the target slug or use the full URL with your CMS lookup.
- Load exactly one editable page.
- Use an Iterator for
data.fixesonly when each module supports the required type safely. - Route fixes by
type. - For
content_replacement, replace only an exactcurrent_valuematch. - For metadata, schema, or image fixes, use the correct CMS field or protected API endpoint.
- Aggregate the changes and update the page once where possible.
- Add Webhook Response after the update with the destination ID and final URL.
For a complete mixed fix list, the safest Make design is:
Custom webhook → Router(fix.apply) → HTTP: protected fix endpoint
→ Webhook Response
The protected endpoint receives target_url and the full fixes list, validates every instruction, updates the CMS transactionally, and returns {id, link}. This avoids saving a partially updated page after each Iterator cycle.
9. Other tools and custom webhook receivers
Use the same design for Pipedream, Activepieces, Workato, Power Automate, a serverless function, or your own backend:
HTTP POST trigger
→ verify signature when supported
→ deduplicate event id
→ switch on event
→ content.generated article: publish
→ fix.apply: find page and apply fixes
→ test/completion: acknowledge only
→ return a clear HTTP response
For article and fix success:
{
"id": "destination-record-id",
"link": "https://example.com/final-page"
}
Return a non-2xx response with a clear message when the operation was not safely completed:
{
"error": "content_conflict",
"message": "The page changed after the audit. current_value no longer matches."
}
Custom receivers should verify X-ContentKit-Signature using the signing secret and raw request body. See signature verification and the full event contract.
10. Test before activation
Complete all of these checks:
- Send Test Event produces
event: testand no website change. - One article event creates or updates exactly one intended article.
- A publish summary containing
published_countcreates nothing. - One
fix.applyupdates the page indata.target_url, not another page. - A
current_valuemismatch stops the replacement. fix.generatedcreates no additional update.- Replaying the same event ID creates no duplicate.
- Failed CMS actions are visible in Zap History, n8n executions, Make history, or your server logs.
- Secrets and CMS credentials are stored in the automation platform's protected connection/secret storage.
- Backups or revision history can restore the test page.
