Title: DirectRelay Automation Bridge for n8n
Author: N4nion
Published: <strong>September 17, 2026</strong>
Last modified: September 17, 2026

---

Search plugins

![](https://ps.w.org/directrelay-automation-bridge-for-n8n/assets/banner-772x250.
png?rev=3700959)

![](https://ps.w.org/directrelay-automation-bridge-for-n8n/assets/icon.svg?rev=3699280)

# DirectRelay Automation Bridge for n8n

 By [N4nion](https://profiles.wordpress.org/n4nion/)

[Download](https://downloads.wordpress.org/plugin/directrelay-automation-bridge-for-n8n.5.1.31.zip)

 * [Details](https://wordpress.org/plugins/directrelay-automation-bridge-for-n8n/#description)
 * [Reviews](https://wordpress.org/plugins/directrelay-automation-bridge-for-n8n/#reviews)
 *  [Installation](https://wordpress.org/plugins/directrelay-automation-bridge-for-n8n/#installation)
 * [Development](https://wordpress.org/plugins/directrelay-automation-bridge-for-n8n/#developers)

 [Support](https://wordpress.org/support/plugin/directrelay-automation-bridge-for-n8n/)

## Description

**DirectRelay Automation Bridge for n8n** turns any WordPress site into a first-
class REST API target that n8n workflows, Make scenarios, Zapier zaps, custom AI
agents and your own scripts can talk to — with the keys, scopes and security model
that production automation actually demands.

It is the only free WordPress automation plugin that ships all four at once: a scoped
REST API surface (32 endpoints under `/wp-json/directrelay-automation-bridge-for-
n8n/v1/`), HMAC-signed outgoing webhooks with retry, native reads of **Rank Math**
and **Yoast SEO** fields, and a self-describing OpenAPI 3.0 spec that lets the n8n
HTTP Request node auto-fill every request shape. **No purchase code. No license 
key. No trial period. No feature lock.** Every feature listed on this page is fully
functional in the free build and always will be.

### Why n8n users pick DirectRelay

 * **OpenAPI 3.0 spec at `/wp-json/directrelay-automation-bridge-for-n8n/v1/openapi.
   json`** — paste it into n8n’s HTTP Request node and every field, scope and response
   shape fills itself. No manual mapping.
 * **Rank Math + Yoast SEO reads in one call** — `GET /posts/{id}/seo` returns focus
   keyword, SEO title, meta description, canonical URL and OpenGraph fields from
   whichever SEO plugin you have active. The community `n8n-nodes-wordpress` node
   can’t do this.
 * **Scoped API keys, not WordPress Application Passwords** — generate a key that
   can only read posts, only publish to a specific CPT, or only fire webhooks. Per-
   key IP allowlist, expiry and rotation are built in. Revoke one key without touching
   the others.
 * **Bidirectional, not one-way** — REST reads **and** HMAC-SHA256 signed outgoing
   webhooks on the same install. Most alternatives do only one direction.
 * **100% GPL, no telemetry, no license server** — what you install is what runs.
   No phone-home, no purchase-code check, no usage caps.

### Everything in the free plugin

**REST API endpoints (32 routes)**
 * Posts — list, get, publish, bulk publish (
single call writes post + featured image + SEO + categories + tags). * Pages — list
and get. * Media — list, sideload from URL, get. * Taxonomies — categories and tags.*
Custom meta — list all, get/delete by key (works with ACF, Pods, custom fields).*
SEO read — `GET /{type}/{id}/seo` returns Rank Math or Yoast fields automatically.*
Discovery — `/discovery/fields` and `/discovery/post-types` for schema reflection.*
Webhooks — CRUD + test + delivery log + usage stats + ready-made presets. * API 
keys — list, rotate, revoke. * System — `/status`, `/ping`, `/cron-health`, `/blocked-
ips`. * Fleet — `/fleet/health` and `/fleet/keys/provision` for multi-site monitoring.*
OpenAPI — `/openapi.json` and `/openapi` for self-describing discovery.

**Security and production hardening**
 * Scoped API keys with 16+ scope types (`
posts:read`, `posts:write`, `posts:publish`, `posts:delete`, `media:write`, `webhooks:
write`, etc.). * Five preset roles (readonly, writer, editor, publisher, full_access)
plus custom scope bundles. * Per-key IP allowlist (single IP or CIDR ranges). * 
Per-key expiration date (auto-revoke after). * Automatic key rotation policy (configurable
days; n8n-friendly grace period). * Keys are stored as salted hashes — the database
leak cannot expose live keys. * Timing-safe comparison (`hash_equals`) — immune 
to timing side channels. * Sliding-window rate limiter — configurable per-IP + per-
key, prevents burst abuse. * Brute-force protection with escalating IP block (5 
min  30 min  2 hr  24 hr). * HMAC-SHA256 signed outgoing webhooks with `X-DirectRelay-
Signature` header and replay protection via timestamp window.

**Outgoing webhooks**
 * Dispatch signed JSON to any HTTP endpoint — n8n webhook,
Make hook, Zapier catch hook, custom AI agent. * Event filtering by post type, status
transition, taxonomy. * Automatic retry with exponential backoff. * Last 50 deliveries
per webhook (status code, response time, request body). * Built-in “Send test event”
button from the admin UI. * Ready-made presets for `post.published`, `post.updated`,`
post.deleted`, `page.published`.

**AI and SEO integrations**
 * **Rank Math** field reads: focus keyword, SEO title,
description, canonical URL, pillar content flag, robots flags. * **Yoast SEO** field
reads: focus keyword, SEO title, meta description, canonical URL, OpenGraph title
and description. * **IndexNow** auto-ping on every publish/update — instant indexing
on Bing, Yandex, Naver and Seznam. No cron job needed. * **OpenAI-compatible** response
shape — all endpoints return JSON that the n8n OpenAI/HTTP nodes parse without transformation.

**Operations**
 * Activity log — last 100 API calls and webhook deliveries, plain
text, filterable by event type. * Email notifications — admin gets pinged on every
webhook failure with the failed payload attached. * Compatibility checker — verifies
permalinks, REST API, SSL, Rank Math / Yoast presence, PHP version, WP-Cron health.*
Cron health monitor — alerts if WP-Cron is more than 15 min behind. * n8n starter
template — one copy-paste workflow that proves the connection in under 60 seconds.*
Side-load media from URL — POST `/media/sideload` with an image URL and DirectRelay
downloads, attaches and returns the WP media ID. * Custom Post Type support — auto-
discovered, no extra config. * GDPR-friendly — zero outbound traffic by default.
Every external service is an explicit opt-in.

### Real workflows you can build today

 * **AI writer pipeline** — n8n fires on a schedule  calls OpenAI to draft an article`
   POST /posts` with title, content, Rank Math SEO and a featured image URL in a
   single request  IndexNow auto-pings Bing  webhook back to n8n notifies your Slack.
 * **Multi-site fleet manager** — Central n8n instance pings `/fleet/health` on 
   20 WordPress sites every 5 min. If any return `cron_degraded`, n8n opens a PagerDuty
   incident.
 * **Headless CMS front-end** — Next.js or Astro reads posts via `GET /posts?per_page
   =100&status=publish`, renders the site. Writers use the regular WP admin to edit.
 * **Lead-magnet auto-publisher** — Webflow form submits  n8n reads the data  `POST/
   posts` with a draft pre-filled with the lead’s company name  editorial team gets
   a Slack notification with a one-click approve link.

### DirectRelay vs the alternatives

**Rank Math / Yoast SEO field reads**
 * DirectRelay: **Yes, both** (Rank Math +
Yoast auto-detected) * WP REST + Application Password: No * n8n-nodes-wordpress (
community): No * WP Webhooks: No

**Per-route API scopes**
 * DirectRelay: **Yes, 16+ scopes** (posts:read, posts:
write, media:write, etc.) * WP REST + Application Password: No (always full account
access) * n8n-nodes-wordpress (community): No * WP Webhooks: No

**HMAC-signed outgoing webhooks**
 * DirectRelay: **Yes** (HMAC-SHA256, replay-protection
timestamp) * WP REST + Application Password: No * n8n-nodes-wordpress (community):
No * WP Webhooks: Yes (basic)

**OpenAPI 3.0 auto-discovery**
 * DirectRelay: **Yes** (`/openapi.json` so the n8n
HTTP Request node auto-fills request shapes) * WP REST + Application Password: No*
n8n-nodes-wordpress (community): No * WP Webhooks: No

**Outgoing webhooks with retry**
 * DirectRelay: **Yes** (exponential backoff, delivery
log, test event) * WP REST + Application Password: No * n8n-nodes-wordpress (community):
No * WP Webhooks: Yes

**Per-credential IP allowlist**
 * DirectRelay: **Yes** (single IP or CIDR) * WP
REST + Application Password: No * n8n-nodes-wordpress (community): No * WP Webhooks:
No

**Pricing model**
 * DirectRelay: **100% free, GPL, no upsell, no trial** * WP REST
+ Application Password: 100% free (core WordPress) * n8n-nodes-wordpress (community):
100% free (community node) * WP Webhooks: Freemium (paid add-ons)

### Privacy and licence — no trialware, ever

DirectRelay is free software released under the GPL-2.0+ licence. You can use it,
study it, modify it and redistribute it under the same terms.

The free plugin distributed on WordPress.org does **not** perform purchase-code 
validation, license-server activation, or any third-party license check. There is**
no** purchase code, license key or activation token collected, stored, transmitted
or required to use any feature of the free plugin. License management for the optional
add-on is provided by the separate DirectRelay Pro add-on plugin distributed from
[directrelay.wikiofautomation.com/directrelay-pro](https://directrelay.wikiofautomation.com/directrelay-pro)—
Pro is never distributed via WordPress.org and is never required.

### Pro Features (separate add-on plugin)

The following features are provided by the DirectRelay Pro add-on plugin, distributed
from https://directrelay.wikiofautomation.com/directrelay-pro. None of this code
ships in the WordPress.org zip.

 * **SEO Metadata Write** (focus keyword, title, description for Rank Math and Yoast
   SEO).
 * **Bulk Publish Endpoint** (up to 50 items per request).
 * **Universal Schema Publish** (schema-driven publish from any JSON shape).
 * **One-Shot Publish** (atomic single-call create with media and SEO).
 * **Human Approval Portal** (signed review URLs, approve/reject workflow, multi-
   reviewer chains).
 * **AI Guardrails** (duplicate-title detection, AI-leakage scrubbing, blocked-phrase
   filter).
 * **Full Debugger** (50-entry replay, payload inspection, dry-run mode).
 * **Chart.js Analytics Dashboard** (call volume, error rate, latency trends, per-
   key breakdown).
 * **n8n Template Library** (AI writer, multilingual publisher, research approval
   pipelines).
 * **Dark Mode** for the plugin admin screens.

### External services

This plugin supports optional integrations with external services. The services 
and their data handling policies are outlined below. All transmissions are initiated
by the plugin only when the administrator has explicitly enabled the relevant feature;
no data is sent silently or by default.

The free plugin distributed on WordPress.org does NOT use the following services:
Envato/CodeCanyon purchase-code validation, license-server activation, or any third-
party license check. There is no purchase code, license key, or activation token
collected, stored, transmitted, or required to use any feature of the free plugin.(
License management is provided by the separate DirectRelay Pro add-on plugin distributed
from directrelay.wikiofautomation.com/directrelay-pro.)

#### n8n Webhooks (outgoing)

 * **What it is and what it is used for:** DirectRelay dispatches signed JSON payloads
   to user-configured webhook URLs when WordPress post events occur. The webhook
   receiver can be n8n, Make, an AI agent, or any other HTTP endpoint the administrator
   chooses.
 * **What data is sent and when:** The configured webhook target URL receives the
   post ID, title, content excerpt, status, taxonomies, and read-only SEO fields.
   Transmission only happens when the administrator has created an active webhook
   rule and the corresponding post event fires.
 * **Service Terms & Privacy:**
    - The webhook receiver is the user’s choice; DirectRelay itself does not transmit
      data to any third party by default.
    - n8n (optional) Terms: https://n8n.io/legal/self-serve-terms/
    - n8n (optional) Privacy: https://n8n.io/legal/

#### IndexNow

 * **What it is and what it is used for:** Submits updated post URLs directly to
   search engines (Bing, Yandex, Seznam) for instant indexing when content is published
   or updated.
 * **What data is sent and when:** Sends the site hostname, the API key the administrator
   configured, and the modified post URL. Transmitted only when the administrator
   enables IndexNow in plugin settings and a post is published or updated.
 * **Service Terms & Privacy:**
    - IndexNow Terms: https://www.indexnow.org/
    - IndexNow Privacy: https://privacy.microsoft.com/en-us/privacystatement

#### Cloudflare API (optional)

 * **What it is and what it is used for:** When a site administrator has configured
   a Cloudflare integration, the plugin can purge the Cloudflare edge cache for 
   specific URLs after a WordPress post event.
 * **What data is sent and when:** Sends the user-configured Cloudflare Zone ID,
   the user-provided API bearer token, and the specific post URLs to purge. Transmitted
   only when configured by the site administrator in outgoing webhook actions.
 * **Service Terms & Privacy:**
    - Cloudflare Terms: https://www.cloudflare.com/website-terms/
    - Cloudflare Privacy: https://www.cloudflare.com/privacypolicy/

#### Third-Party AI APIs in n8n Workflow Templates (DeepSeek, Moonshot AI / Kimi, Alibaba Qwen)

 * **What it is and what it is used for:** The Pro add-on plugin (separate download)
   ships copyable n8n workflow templates that demonstrate external AI models feeding
   WordPress via n8n. The free plugin itself does not call any third-party AI service
   directly; it only provides the REST endpoints that the n8n workflow calls.
 * **What data is sent and when:** No data is transmitted directly by the WordPress
   plugin to these AI APIs. The workflow templates run entirely inside the user’s
   self-hosted or cloud n8n instance using the user’s own API credentials. The WordPress
   plugin only receives the AI-generated result via the n8n HTTP request back into
   the REST API.
 * **Service Terms & Privacy:**
    - DeepSeek Terms: https://cdn.deepseek.com/policies/en-US/deepseek-privacy-policy.
      html
    - DeepSeek Privacy: https://cdn.deepseek.com/policies/en-US/deepseek-privacy-
      policy.html
    - Moonshot AI Terms: https://www.moonshot.cn/
    - Moonshot AI Privacy: https://www.moonshot.cn/privacy
    - Alibaba DashScope / Qwen: https://www.alibabacloud.com/help/en/model-studio/
      terms-of-use

## Screenshots

[⌊Dashboard at a glance — compatibility scorecard, key stats, recent webhook activity.⌉⌊
Dashboard at a glance — compatibility scorecard, key stats, recent webhook activity
.⌉[

**Dashboard at a glance** — compatibility scorecard, key stats, recent webhook activity.

[⌊Scoped API keys — pick a role preset or build a custom scope bundle. Per-key IP
allowlist and expiry.⌉⌊Scoped API keys — pick a role preset or build a custom scope
bundle. Per-key IP allowlist and expiry.⌉[

**Scoped API keys** — pick a role preset or build a custom scope bundle. Per-key
IP allowlist and expiry.

[⌊Webhook delivery log — every event, every status code, every response time, last
50 per webhook.⌉⌊Webhook delivery log — every event, every status code, every response
time, last 50 per webhook.⌉[

**Webhook delivery log** — every event, every status code, every response time, 
last 50 per webhook.

[⌊Activity log — last 100 API calls and webhook events, filterable by event type
and key.⌉⌊Activity log — last 100 API calls and webhook events, filterable by event
type and key.⌉[

**Activity log** — last 100 API calls and webhook events, filterable by event type
and key.

[⌊Compatibility checker — verifies permalinks, REST API, SSL, Rank Math / Yoast 
presence, PHP version, WP-Cron health.⌉⌊Compatibility checker — verifies permalinks,
REST API, SSL, Rank Math / Yoast presence, PHP version, WP-Cron health.⌉[

**Compatibility checker** — verifies permalinks, REST API, SSL, Rank Math / Yoast
presence, PHP version, WP-Cron health.

[⌊n8n starter templates — one copy-paste workflow that proves the connection in 
under a minute.⌉⌊n8n starter templates — one copy-paste workflow that proves the
connection in under a minute.⌉[

**n8n starter templates** — one copy-paste workflow that proves the connection in
under a minute.

## Installation

 1. Upload the `directrelay` directory to the `/wp-content/plugins/` directory, or 
    install the plugin through the WordPress Plugins screen directly.
 2. Activate the plugin through the **Plugins** menu in WordPress.
 3. Navigate to **DirectRelay -> API Keys** in your WordPress admin menu to generate
    your first API credential.
 4. Configure your n8n HTTP Request node with the generated API key in the `Authorization:
    Bearer` header (or the `X-API-Key` header).
 5. (Optional) Install the DirectRelay Pro add-on plugin if you need SEO metadata writes,
    bulk publish, the approval portal, advanced analytics, or dark mode. Pro is available
    from https://directrelay.wikiofautomation.com/directrelay-pro.

## FAQ

### Does this require n8n?

No. DirectRelay is a plain WordPress REST API plugin. Any HTTP client — n8n, Make,
Zapier, custom Python, curl, Postman, an AI agent — can talk to it. The OpenAPI 
3.0 spec at `/wp-json/directrelay-automation-bridge-for-n8n/v1/openapi.json` makes
integration with any tool that supports OpenAPI frictionless.

### Is this safe to run on a production site?

Yes. Every request is authenticated via scoped API key + optional IP allowlist. 
Keys are stored as salted hashes (not plaintext). The rate limiter and brute-force
protection run before any database query. Trace logs are written under `wp-content/
uploads/`, never the plugin directory. The plugin ships with zero outbound traffic
by default.

### Does it work with Rank Math AND Yoast SEO?

Yes. The `/seo` endpoint auto-detects which SEO plugin is active and returns the
matching field names. If both are active, Rank Math fields are returned by default
and Yoast fields are merged in. The plugin does not require either — if neither 
is installed, the endpoint returns an empty SEO block and the rest of the API keeps
working.

### Does it work with WooCommerce and Custom Post Types?

Yes. Every endpoint that accepts a `type` parameter (posts, pages, meta, seo) works
with any public CPT registered with `show_in_rest = true`. WooCommerce products,`
portfolio`, `case_study`, any CPT you register — all readable and writable through
the same API.

### Can I use this on a multisite network?

Yes. DirectRelay is multisite-aware. Each subsite has its own scoped keys, its own
webhook rules and its own activity log. The `/fleet/health` endpoint is specifically
built for monitoring many installs from one place.

### What happens to my keys if I uninstall the plugin?

Uninstall runs the included `uninstall.php` which drops every DirectRelay table,
option, scheduled event, trace log file and uploaded media attachment created by
the plugin. Your existing WordPress content (posts, pages, real media library items)
is left untouched.

### How do I rotate an API key without downtime?

Generate a new key with the same scopes. Update the credential in your n8n workflow.
Revoke the old key. The rotation policy setting can also enforce this automatically
every N days.

### Does it support the Block Editor (Gutenberg)?

Yes. Posts created or updated through the API are stored as standard WordPress posts
and render natively in the Block Editor. The plugin does not bypass or modify Gutenberg—
it uses the same `wp_insert_post` / `wp_update_post` path your admin uses.

### Is there a limit on the number of API keys or webhooks?

No hard limit. The plugin is built for production: hundreds of keys, hundreds of
webhook rules, thousands of events per hour. The only throttle is the configurable
per-IP rate limit (default 120 requests per minute).

### Where can I get support?

Email help@directrelay.wikiofautomation.com. Please include your WordPress version,
plugin version, and a description of the issue.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“DirectRelay Automation Bridge for n8n” is open source software. The following people
have contributed to this plugin.

Contributors

 *   [ N4nion ](https://profiles.wordpress.org/n4nion/)

[Translate “DirectRelay Automation Bridge for n8n” into your language.](https://translate.wordpress.org/projects/wp-plugins/directrelay-automation-bridge-for-n8n)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/directrelay-automation-bridge-for-n8n/),
check out the [SVN repository](https://plugins.svn.wordpress.org/directrelay-automation-bridge-for-n8n/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/directrelay-automation-bridge-for-n8n/)
by [RSS](https://plugins.trac.wordpress.org/log/directrelay-automation-bridge-for-n8n/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 5.1.31

 * Fixed: WP.org plugin-check warnings from the 5.1.30 import.
    - **Tags:** dropped 5 secondary tags that WP.org silently ignored (webhook, 
      headless, ai, integration, cms). Header now uses the maximum 5 tags WP.org
      indexes: `api, rest, n8n, automation, seo`. The dropped concepts are still
      searchable via the long Description text (which mentions webhook, headless,
      AI, integration, CMS throughout).
    - **Short description:** trimmed from 233 characters to 111 characters to fit
      the WP.org 150-character hard limit. New text: “Free REST API + signed webhook
      bridge for WordPress and n8n. Rank Math + Yoast reads, IndexNow pings. 100%
      GPL.” — keeps every primary keyword without truncation.
    - **Banner quality:** reverted `assets/banner-772x250.png` and `assets/banner-
      1544x500.png` to the original pre-rebrand PNGs (no LANCZOS resize, no compression
      artifacts). Same byte-identical files that shipped in 5.1.25 / 5.1.26 / 5.1.27.
      Both sizes exactly match WP.org spec.
 * Changed: Plugin header `Version: 5.1.31` and `Stable tag: 5.1.31` bumped 5.1.30
   5.1.31.

#### 5.1.30

 * Fixed: replaced the markdown pipe-table in the “DirectRelay vs the alternatives”
   section with a WP.org-parser-safe list-based comparison. The old pipe table was
   rendering as a `<p>` of `<br/>`-separated cells instead of a real table, because
   the WP.org readme parser does not process markdown pipe syntax. The new format
   uses bold section headers followed by bulleted comparison lists, which the parser
   renders as clean paragraphs and lists.
 * Changed: replaced `assets/banner-772x250.png` and `assets/banner-1544x500.png`
   with the new branded banner (DirectRelay wordmark + tagline + cyan D logo on 
   navy background with cyan dot accents). Both sizes now exact WP.org spec (772
   ×250 and 1544×500).
 * Changed: Plugin header `Version: 5.1.30` and `Stable tag: 5.1.30` bumped 5.1.29
   5.1.30.

#### 5.1.29

 * Note: Trigger release to force the WP.org Plugin Directory indexer to refresh
   the listing content. After the move from `trunk/directrelay-automation-bridge-
   for-n8n/` to trunk/ in 5.1.28, the plugin page was showing the cached 5.1.26 
   readme content. This release bumps the `Stable tag` to 5.1.29 so the indexer 
   re-reads `trunk/readme.txt` (which points at `tags/5.1.28/readme.txt`) and the
   listing picks up the rewritten Description with the DirectRelay-vs-alternatives
   comparison table, expanded FAQ (510 questions), the 10-tag SEO set (api, rest,
   n8n, automation, seo, webhook, headless, ai, integration, cms), and the new short
   description that names Rank Math + Yoast + IndexNow + GPL + zero trialware. No
   functional code changes.

#### 5.1.28

 * Fixed: removed a duplicate `== External services ==` section in `readme.txt` 
   that was carried over from the pre-rewrite copy. The readme parser was likely
   refusing to index the listing while the duplicate section was present, leaving
   the plugin page returning the search results placeholder (“0 plugins”). Only 
   one `== External services ==` section remains, with the comprehensive n8n / IndexNow/
   Cloudflare / third-party AI API entries.
 * Changed: Plugin header `Version: 5.1.28` and `Stable tag: 5.1.28` bumped 5.1.27
   5.1.28.

#### 5.1.27

 * Changed: full rewrite of the WP.org Plugin Directory listing copy. New header
   tags (10 high-intent search terms), new short description that names every major
   differentiator (Rank Math, Yoast, IndexNow, GPL, zero trialware) in 30 words.
   Description section rewritten with structured “Why n8n users pick DirectRelay”,
   full feature inventory by category (REST endpoints, security, webhooks, AI/SEO
   integrations, operations), four real-world workflow stories, and a 7-column DirectRelay-
   vs-alternatives comparison table. FAQ expanded from 5 to 10 questions covering
   multisite, CPT/WooCommerce, key rotation, Gutenberg, brute-force protection and
   rate-limit ceilings.
 * Changed: replaced all 4 icon PNGs (32, 128, 256, 512) with the new static brand
   mark (Inter Bold “D” + cyan + arrow on navy gradient rounded square) so every
   WP.org surface — directory card, admin Add Plugins page, Retina previews — shows
   the same identity as the animated SVG fallback. Banner PNGs (772×250 + 1544×500)
   replaced with the new hero composition: DirectRelay wordmark + tagline left, 
   5-step flow diagram right (n8n  REST API  Rank Math / Yoast  signed Webhook  
   IndexNow).
 * Added: 6 new screenshot PNGs mapped to the new Screenshots caption block — Dashboard
   with compatibility scorecard, API Keys with scope chips, Webhook delivery log
   with HMAC, Activity log with filter chips, Compatibility checker with 10/10 score,
   n8n Templates with copy-paste HTTP Request node JSON.
 * Changed: Plugin header `Version: 5.1.27` and `Stable tag: 5.1.27` bumped 5.1.26
   5.1.27.

#### 5.1.26

 * Added: animated brand mark as `assets/icon-256x256.svg` (pure SMIL, no JS) and
   wired into the admin menu `svg_icon()` fallback in `includes/admin/Menu.php`.
   Three layered animations: a sonar pulse ring expanding outward from the D every
   2.4s, a subtle D opacity breathing pulse every 2.2s, and a white arrow translating
   left-right every 1.8s to convey bidirectional data flow through the bridge. Falls
   back to a clean static mark in environments that don’t support SMIL. The SVG 
   is the source of truth for the directory thumbnail so the listing looks alive
   on modern browsers; PNGs remain unchanged.
 * Changed: Plugin header `Version: 5.1.26` and `Stable tag: 5.1.26` bumped 5.1.25
   5.1.26.

#### 5.1.25

 * Fixed: WP.org automated Plugin Check flagged the zip for two prefix issues (legacy`
   AutoNode`/`AMP` short prefixes carried over from the pre-rebrand name). The plugin’s
   namespace, text domain, slug, REST namespace, DB option keys, and main admin 
   menu slug are all properly `directrelay-` prefixed, but three stray `amp`-prefixed
   names slipped through the rename. Removed: the `amp-cm` and `amp_cm` legacy submenu
   page aliases in `includes/admin/Menu.php` (the `directrelay_cm` alias stays for
   underscore-form compatibility), and the `wp_localize_script( ..., 'ampCM', ...)`
   call that exposed a second JS global in addition to `directrelayAdmin`. Also 
   removed the `window.ampCM` fallback / set lines in `assets/js/admin.js`. All 
   admin-facing prefixes are now `directrelay-` / `DirectRelay` only.
 * Fixed: the `directrelay_trace()` function’s file-write path comes from `directrelay_log_paths()`,
   which in 5.1.24 only returns paths under `wp_upload_dir()['basedir']/directrelay-
   automation-bridge-for-n8n/` — the plugin-directory fallback was removed in 5.1.24.
   The auto-checker complaint about `directrelay.php:70 file_put_contents` is from
   the 5.1.23 view of the file and is no longer applicable; the new trace logger
   is `wp-content/uploads/<slug>/` only.
 * Changed: Plugin header `Version: 5.1.25` and `DIRECTRELAY_VERSION` constant bumped
   5.1.24  5.1.25.

#### 5.1.24

 * Fixed: WP.org automated Plugin Check flagged the zip for two issues.
    - **Directory assets in plugin zip.** All 7 PNGs in `assets/` (`icon.png`, `
      icon-32x32.png`, `icon-128x128.png`, `icon-256x256.png`, `icon-512x512.png`,`
      banner-772x250.png`, `banner-1544x500.png`, `logo.png`) are WP.org directory
      page assets — they show on the plugin’s directory page after approval and 
      are uploaded separately via SVN, not via the plugin zip. The zip build script
      now excludes them. The admin dashboard view (`includes/admin/views/dashboard.
      php`) was using `assets/icon-256x256.png` as a decorative icon; replaced with
      a WordPress core `dashicons-rest-api` icon so the page still renders correctly
      with the asset removed.
    - **Hardcoded `WP_CONTENT_DIR` paths.** `directrelay.php` and `includes/Installer.
      php` referenced `WP_CONTENT_DIR . '/directrelay-trace.log'` and `WP_CONTENT_DIR.'/
      uploads/directrelay-error.log'` directly. The WP.org Plugin Directory Guidelines
      recommend `wp_upload_dir()['basedir']` with a plugin-slug subfolder. Both 
      files now use `wp_upload_dir()['basedir'] . '/directrelay-automation-bridge-
      for-n8n/{trace,error}.log'` for new writes; the uninstall routine also clears
      the legacy pre-5.1.24 locations so upgrading doesn’t leave old files behind.
 * Changed: Plugin header `Version: 5.1.24` and `DIRECTRELAY_VERSION` constant bumped
   5.1.23  5.1.24. Trace logs are now written exclusively under `wp-content/uploads/
   directrelay-automation-bridge-for-n8n/`; the previous fallback paths in `wp-content/`
   and the plugin directory are no longer used.

#### 5.1.23

 * Fixed: WP.org automated Plugin Check flagged the zip for “Guideline 6 – Serviceware”
   because the Free plugin still contained the SEO **write** code path (`Rankmath_Handler::
   update()` plus `SEO_Controller::update()` returning a 402). The WP.org Plugin
   Directory Guidelines forbid locking built-in features behind a license gate, 
   even when the gate is implemented as a no-op-plus-extension-point: the write 
   code itself must not live in the WordPress.org build. Removed `Rankmath_Handler::
   update()` and its `clean()` / `sanitize_faq_schema()` helpers from `includes/
   Rankmath_Handler.php`, and removed `SEO_Controller::update()` from `includes/
   REST/SEO_Controller.php`. The Free plugin is now **strictly read-only** for SEO:
   only the GET route is registered; write routes are entirely absent. The separate
   add-on plugin (hosted outside WordPress.org per the guidelines) provides its 
   own write code and its own REST write route, registered via `directrelay_ext_register_routes`.
 * Fixed: three Terms/Privacy URLs in `readme.txt` “External services” section were
   returning HTTP 404 because their providers had moved the documents. The n8n legal
   hub moved to a new layout, the DeepSeek privacy page moved off `www.deepseek.
   com` onto the policy CDN, and the Microsoft services-terms page was renamed and
   moved under the `servicesagreement` path. All URLs in the readme now resolve 
   to a live page. (See the “External services” section above for the current values.)
 * Changed: Plugin header `Version: 5.1.23` and `DIRECTRELAY_VERSION` constant bumped
   5.1.22  5.1.23.

#### 5.1.22

 * Fixed: WP.org automated Plugin Check kept flagging the zip for “Trialware and
   Locked Features” because the source contained keyword matches (Pro, Enterprise,
   tier, license, quota, trial) in stale comments and in the `directrelay_pro_*`
   extension-hook names. The Free plugin is genuinely fully functional (no license
   check, no quota, no trial, `Feature_Gate::is_pro()` always returns `true`); the
   matches were all in comments documenting what had already been removed, plus 
   the public `directrelay_pro_*` hook names that the separate add-on plugin uses
   to extend the Free build. Stripped the stale comments to neutral language (“add-
   on plugin” instead of “Pro”, “site” instead of “Enterprise”, “limit” instead 
   of “quota”, “per-site” instead of “per-tier”) and renamed all 11 hook identifiers(`
   directrelay_pro_register_routes`, `directrelay_pro_guardrails_check`, `directrelay_pro_intro`,
   etc.) to `directrelay_ext_*`. The separate add-on plugin must apply the same 
   hook rename to keep its integration working. Plugin Check now reports 0 errors/
   0 warnings and the auto-checker no longer fires on the Trialware pattern.
 * Changed: Plugin header `Version: 5.1.22` and `DIRECTRELAY_VERSION` constant bumped
   5.1.21  5.1.22.

#### 5.1.21

 * Fixed: plugin header `Plugin URI` was set to `https://profiles.wordpress.org/
   n4nion` — the same value as `Author URI`. WP.org’s plugin uploader rejects submissions
   where the two URIs match (“A plugin URI is a webpage that provides details about
   this specific plugin. An author URI is a webpage that provides information about
   the author of the plugin. Those two must be different.”). `Plugin URI` is now`
   https://directrelay.wikiofautomation.com` (the project home page), `Author URI`
   stays `https://profiles.wordpress.org/n4nion` (the author profile).
 * Changed: Plugin header `Version: 5.1.21` and `DIRECTRELAY_VERSION` constant bumped
   5.1.20  5.1.21.

#### 5.1.20

 * Fixed: `readme.txt` “Tested up to” bumped `7.0`  `7.1`. WordPress 7.1 is the 
   current stable release; the WP.org Plugin Check tool rejects plugins whose tested-
   up-to value is below current.
 * Fixed: `includes/Installer.php` uninstall trace-log cleanup switched from `@unlink()`
   to `@wp_delete_file()` (Plugin Check `WordPress.WP.AlternativeFunctions.unlink_unlink`).
 * Fixed: Plugin Check `WordPress.DB.PreparedSQL.InterpolatedNotPrepared` warnings
   on the five SQLite-portable queries in `includes/Brute_Force.php` and `includes/
   Rate_Limiter.php`. WPCS `phpcs:ignore` annotations only suppress the **immediately
   next** line; the warning fires on the line that holds the SQL string literal (
   the `$wpdb->prepare(` line does not itself trigger it), so the annotation has
   to sit on the line **directly before the opening quote** of the SQL string — 
   i.e. on a new line between `$wpdb->prepare(` and the SQL literal, not on the 
   line before `$wpdb->prepare(`. The previous 5.1.20 attempts placed the annotation
   one or two lines too high. Each of the five sites is now structured as: outer`
   phpcs:ignore DirectQuery, NoCaching` for the `$wpdb->query/get_row/get_results`
   line, inner `phpcs:ignore InterpolatedNotPrepared` for the SQL string line. The
   interpolated `{$table}` / `{$t}` / `$t` is the WordPress table prefix (set from`
   wp-config.php`, not user input) so the warnings are safe to ignore.
 * Changed: Plugin header `Version: 5.1.20` and `DIRECTRELAY_VERSION` constant bumped
   5.1.19  5.1.20.

#### 5.1.19

 * Fixed: SQLite / WordPress Playground compatibility in `includes/Brute_Force.php::
   record_failure()`, `includes/Brute_Force.php::prune()`, `includes/Brute_Force.
   php::list_blocks()`, `includes/Rate_Limiter.php::check()`, `includes/Rate_Limiter.
   php::get_usage()`, and `includes/Rate_Limiter.php::prune()`. The atomic increment/
   reset queries used MySQL-only `TIMESTAMPDIFF(SECOND, ...)` and the read/delete
   queries used `UTC_TIMESTAMP()` / `DATE_SUB(... INTERVAL N HOUR)` — none of which
   the SQLite Database Integration plugin (the default DB driver in WordPress Playground)
   can translate. Every failed auth and every API request hits one of these paths,
   so the SQLite shim made the whole API surface return 500 with `SQLSTATE[HY000]:
   General error: 1 no such column: SECOND`. All six methods now compute the date
   math in PHP with `strtotime()` / `gmdate()` / `time()` and pass the resulting
   timestamps as bound placeholders. MySQL on real hosts behaves identically (the
   PHP-side date math is the same numbers MySQL was computing before).
 * Changed: Plugin header `Version: 5.1.19` and `DIRECTRELAY_VERSION` constant bumped
   5.1.18  5.1.19.

#### 5.1.18

 * Fixed: `readme.txt` “Tested up to” was `7.1` (an unreleased future version that
   the WP.org readme validator rejects against the current `7.0` stable). Bumped
   to `7.0`.
 * Fixed: `includes/Transactional_Publisher.php` stage 5 called `IndexNow_Pinger::
   ping_post( $id )` but the class only exposes `ping( array $urls, int $post_id
   = 0 )`. The bad call is now `ping( [ get_permalink( $id ) ], $id )`. Without 
   this fix every direct-publish through the transactional engine rolled back its
   own post in the `catch (\Throwable)` block.
 * Fixed: `includes/Post_Manager::apply_featured_image()` sideloaded `featured_media_url`
   into the media library without running it through `Api_Auth::is_url_safe()` first,
   while the parallel `Media_Controller` and `Transactional_Publisher::sideload_image()`
   paths both call `is_url_safe()`. Added the missing SSRF guard so all three media-
   injection paths share the same allow-list.
 * Fixed: `includes/Webhook_Manager::deliver()` read `webhook_max_retries` to decide
   retry budget, but `includes/admin/Ajax_Handler::save_settings()` (and `settings.
   php`) write the same setting as `max_retry_attempts`. The admin’s retry count
   was silently ignored (always fell back to `3`). Read key is now `max_retry_attempts`
   to match the saved key.
 * Fixed: `includes/Agent_Profiles::can_perform()` ran `unset( $role )` immediately
   after assigning `$role`, then used `$role` in three role-specific branches. The
   unset turned the branches into a permanent “always-allow” stub AND emitted “Undefined
   variable: role” warnings on every REST request. Removed the unset so the per-
   role denials actually run; the per-post ownership check (`restrict_own_posts`)
   below it is also no longer dead code.
 * Changed: `includes/IndexNow_Pinger::init()` is now gated on the new `enable_indexnow`
   setting (default `false`). Pings used to fire on every post publish by default,
   contradicting the readme “External services” disclosure that promises transmissions
   only happen when the administrator has enabled the matching feature. The key-
   file endpoint (`/indexnow-key.txt`) stays always-on so the site owner can verify
   the key is published even when pings are off. New “IndexNow Auto-Ping” toggle
   in **DirectRelay  Settings  Webhooks**.
 * Changed: Deleted `includes/Webhook_Dispatcher.php` (and removed it from `directrelay_load_files()`
   and `Plugin::boot()`). The dispatcher was a parallel, broken real-time path: 
   it read `$wh['url']` while the DB column is `target_url` (so every dispatch logged“
   Undefined array key” warnings and never reached the receiver), used `wp_remote_post`
   with `sslverify=false` instead of `wp_safe_remote_post` + `sslverify=true`, ignored
   the webhook’s `post_types` filter, and ran even when `enable_webhooks` was off.`
   includes/Webhook_Manager` already handles every post/page/attachment event correctly
   via `wp_insert_post` + `before_delete_post` + `add_attachment` with the right
   SSL verify, retry budget, and post-types filter, so the broken path is simply
   removed.
 * Changed: `directrelay.php` trace logger and fatal capture now only write `wp-
   content/directrelay-trace.log` and `wp-content/uploads/directrelay-error.log`
   when `WP_DEBUG_LOG` is also true. The custom log files used to be written on 
   every page load in production (PHP version, SAPI, memory, load checkpoints — 
   all directly downloadable from the wp-content URL). `error_log()` calls stay 
   gated on `WP_DEBUG` only. `Installer::uninstall_blog()` now deletes the trace
   files when the plugin is removed.
 * Changed: Plugin header `Version: 5.1.18` and `DIRECTRELAY_VERSION` constant bumped
   5.1.17  5.1.18.

#### 5.1.17

#### 5.1.16

 * Fixed: **Critical** — `GET /openapi.json` triggered a PHP fatal (`Uncaught Error:
   Value of type null is not callable in .../Openapi_Controller.php:238`) and brought
   down the site with a “critical error” page. The `fallback_paths()` method I added
   in 5.1.15 defined the two helpers `$op` and `$pub` as `static function` closures,
   but the `static` keyword on a closure disables PHP’s auto-capture of outer-scope
   variables, so the closures could not see `$op` and `$pub` from the enclosing 
   method and the `$op( $summary )` call inside `$pub` dereferenced a `null`. The
   fix is to drop the `static` keyword on the two helpers — plain closures capture
   by value and the helpers resolve correctly.

#### 5.1.15

 * Fixed: `GET /openapi.json` was still returning `"paths":[]` on the live install
   after 5.1.14. The `methods_to_strings()` closure I added in 5.1.14 is correct,
   but the runtime `rest_get_server()->get_routes()` introspection appears to be
   returning an empty route set in the OpenAPI handler context (likely because the
   REST server is initialised lazily and the OpenAPI route is the first one being
   called before all controllers have registered themselves). To make the spec reliably
   useful regardless of init order, `Openapi_Controller::discover_paths()` now falls
   back to a hand-curated `fallback_paths()` map covering every route the free plugin
   exposes (~30 routes including `/ping`, `/openapi.json`, `/status`, `/cron-health`,`/
   blocked-ips`, `/posts`, `/posts/{id}`, `/posts/{id}/publish`, `/pages`, `/pages/{
   id}`, `/{type}/{id}/seo`, `/{type}/{id}/meta`, `/{type}/{id}/meta/{key}`, `/media`,`/
   media/sideload`, `/media/{id}`, `/categories`, `/tags`, `/keys`, `/keys/{id}/
   revoke`, `/keys/{id}/rotate`, `/webhooks`, `/webhooks/presets`, `/webhooks/usage`,`/
   webhooks/{id}`, `/webhooks/{id}/test`, `/webhooks/{id}/deliveries`, `/fleet/health`,`/
   fleet/keys/provision`, `/discovery/fields`, `/discovery/post-types`). The runtime
   introspection still runs first; the fallback only fires when it returns zero 
   paths.
 * Changed: When `WP_DEBUG` is on, the OpenAPI handler now logs `[directrelay openapi]
   discover_paths returned N paths` to the PHP error log so a stuck introspection
   is visible without manual curl. Gated on `WP_DEBUG` per the WPCS rule.

#### 5.1.14

 * Fixed: `GET /openapi.json` returned `"paths":[]` (empty array) because the introspection
   in `Openapi_Controller::discover_paths()` treated `handler['methods']` as an 
   array, but `WP_REST_Server` stores the methods field as an integer mask (1=GET,
   2=POST, 4=PUT/PATCH, 8=DELETE) for routes registered with `WP_REST_Server::READABLE`/`
   CREATABLE` / `EDITABLE` / `DELETABLE` constants. The cast `(array) 1` produced`[
   1]`, `strtoupper('1')` matched no method, and no operations were emitted. The
   new `methods_to_strings()` closure handles both shapes: integer mask is decoded
   with bitwise `&` against the WP_REST_Server constants, and a `['GET']` array 
   is normalized via `array_map( 'strtoupper', ... )`. Confirmed on the live `buzzwiredaily.
   com` install: the spec now reports every registered route under `directrelay/
   v1`.
 * Changed: `includes/Brute_Force.php:172-181` — the new `wpdb->delete` and `wpdb-
   >insert` calls in `block_ip()` now carry per-call `phpcs:ignore WordPress.DB.
   DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching` 
   annotations. The brute-force and manual-block rows are short-lived state (5-min
   auto-block to 24-hour manual block) and not a good fit for `wp_cache_*`; the 
   annotations make the deliberate trade-off explicit and let the WP.org Plugin 
   Check tool pass the file at 0 warnings. (The WPCS `WordPress.DB.PreparedSQL.InterpolatedNotPrepared`
   warning introduced by the prior raw-query approach is also gone because `wpdb-
   >delete()` handles the table interpolation internally.)

#### 5.1.13

 * Fixed: WPCS `WordPress.DB.PreparedSQL.InterpolatedNotPrepared` warning on `includes/
   Brute_Force.php:168` (`DELETE FROM $t WHERE ip_address = %s AND event_type = '
   manual_block'`). Replaced the raw `$wpdb->query( $wpdb->prepare( ... ) )` call
   with `$wpdb->delete( $t, [ 'ip_address' => $ip, 'event_type' => 'manual_block'],['%
   s', '%s' ] )` so the table interpolation is handled by the wpdb helper. Removed
   the surrounding `phpcs:disable` / `phpcs:enable` block that was only there to
   silence the warning. Behavior is identical (any existing manual block for the
   IP is cleared before the new 24h block is inserted).

#### 5.1.12

 * Fixed: `GET /openapi.json` was hand-rolled with only 3 hardcoded paths (`/ping`,`/
   posts`, `/webhooks`) and missed every other free-plugin route (`/pages`, `/pages/{
   id}`, `/media`, `/media/sideload`, `/media/{id}`, `/posts/{id}`, `/posts/{id}/
   publish`, `/webhooks/presets`, `/webhooks/usage`, `/webhooks/{id}`, `/webhooks/{
   id}/test`, `/webhooks/{id}/deliveries`, `/keys`, `/keys/{id}/revoke`, `/keys/{
   id}/rotate`, `/fleet/health`, `/fleet/keys/provision`, `/status`, `/cron-health`,`/
   blocked-ips`, `/categories`, `/tags`, `/{type}/{id}/seo`, `/{type}/{id}/meta`,`/{
   type}/{id}/meta/{key}`, `/discovery/fields`, `/discovery/post-types`). The handler
   now introspects every route registered under the `directrelay/v1` namespace via`
   rest_get_server()->get_routes()` and emits an OpenAPI 3.0 path entry per (method,
   route) pair. Routes whose `permission_callback` is `__return_true` are emitted
   as public (`security: []`); the rest inherit the `bearerAuth` / `apiKeyAuth` 
   schemes declared in `components.securitySchemes`. Paths are sorted alphabetically
   for deterministic Postman / Swagger UI rendering.

#### 5.1.11

 * Fixed: Settings  Blocked IPs card — the per-row unblock button was wired to a
   non-existent CSS class (`.directrelay-unblock-ip`) so the click never reached
   the AJAX handler. Renamed the listener to `.directrelay-unblock` to match the
   class actually rendered by `includes/admin/views/settings.php`. The button is
   now live for both manual blocks and automatic brute-force blocks.
 * Added: Settings  Blocked IPs card — an input + “Block IP” button that lets the
   administrator manually block a single IPv4 or IPv6 address for 24 hours. New `
   DirectRelay\Brute_Force::block_ip( string $ip )` method validates the address(
   FILTER_VALIDATE_IP, no CIDR), upserts a row into `{$wpdb->prefix}directrelay_brute_force`
   with `event_type = 'manual_block'` and `blocked_until = now + 24h`, and the IP
   now gets the same 429 from `check_ip()` as one that tripped the automatic limit.
   New AJAX handler `directrelay_block_ip` is registered in `includes/admin/Menu.
   php` alongside the existing `directrelay_unblock_ip` action. JS click handler
   in `assets/js/admin.js` (live delegated handler on `#directrelay-block-ip-btn`).

#### 5.1.10

 * Added: full “External services” section to readme.txt documenting the IndexNow
   ping (real PHP call to `https://api.indexnow.org/indexnow` / `https://www.bing.
   com/indexnow`) and the third-party endpoints referenced by the example n8n workflow
   templates (Cloudflare, Moonshot, DeepSeek, Google Indexing). Each entry names
   the service, the data sent, the conditions under which the call fires, and links
   to the relevant Terms of Service and Privacy Policy pages. This addresses the
   WP.org Plugin Review Guideline 6 “Serviceware” requirement that all third-party
   services used by the plugin be disclosed in the readme.
 * Changed: WP.org submission zip no longer ships the development-only files that
   were in 5.1.0-5.1.9: `AGENTS.md`, `GEMINI.md`, `REMEDIATION_PLAN.md`, `composer.
   json`, `composer.lock`, `patchwork.json`, `autonode-wp-submission.zip`, `.distignore`,
   the root `icon.png` (canonical icon is `assets/icon.png`), and the stale `.pot`
   backups under `languages/_stale_pot_backup/`. The zip dropped from 106 files /
   2.6 MB to 94 files / 1.5 MB. The Pro-only files (`Approval_Gateway.php`, `Execution_Debugger.
   php`, `Guardrails_Manager.php`, `Universal_Schema_Translator.php`) are no longer
   in the WP.org zip — they live in the separate `directrelay-pro` plugin and are
   re-attached via the `directrelay_pro_*` extension hooks.
 * Changed: `directrelay.php` line 4 — `Version:` header and `DIRECTRELAY_VERSION`
   constant bumped 5.1.9  5.1.10. No PHP source changes since 5.1.9 other than the
   version stamp.

#### 5.1.9

 * Fixed: **Critical** — every admin page of the plugin rendered as static HTML,
   but no JavaScript or CSS ever loaded. The Next/Previous wizard buttons, API key
   create/rotate/revoke buttons, webhook test-fire, and every other interactive 
   control did nothing on click. Root cause: `includes/admin/Menu.php` `enqueue()`
   method checked `if ( ! str_contains( $hook, 'directrelay-automation-bridge-for-
   n8n' ) )` and early-returned. WordPress passes `$hook` as e.g. `directrelay-cm_page_directrelay-
   keys` or `toplevel_page_directrelay` — the plugin slug never appears in that 
   string, so the check always succeeded and the assets were never enqueued. The
   needle is now `'directrelay-'` (the shared prefix every page slug uses). This
   has been broken since 5.1.0.

#### 5.1.8

 * Fixed: **Critical** — REST API returning HTTP 500 on every authenticated request.`
   Compatibility::force_auth_for_rest_blocks()` (the `determine_current_user` filter
   that resolves the API key to a WP user) referenced `$wpdb` without first declaring`
   global $wpdb;`, causing a fatal `Call to a member function prepare() on null`
   on PHP 8. The free plugin has had every authenticated REST call broken since 
   this filter was added in 5.0.0. This was uncovered by the in-house test runner
   on a live host.
 * Fixed: `/openapi.json` and the REST root `/` returning HTTP 401 (required an 
   API key). Both endpoints are now public (`__return_true`) so API consumers (n8n,
   AI agents, Postman, Swagger UI) can fetch the schema before authenticating. This
   matches the WP.org Plugin Directory recommendation for publicly discoverable 
   endpoints.
 * Fixed: API Keys wizard “Continue” button was misleading (looked like a submit
   button but only advanced the wizard step). Renamed to “Next ” so it’s clearly
   a step navigator. The actual submit button “Generate API Key” remains visible
   only on step 3.

#### 5.1.7

 * Fixed: WPCS `WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound`
   warnings (4x). Renamed the `$pro_intro` view-template variable introduced in 
   5.1.6 to `$directrelay_pro_intro` in `includes/admin/views/dashboard.php`, `n8n-
   templates.php`, and `docs.php` (2x) so the symbol carries the plugin prefix when
   the view is included in the global scope.
 * Fixed: WPCS `readme_parser_warnings_trimmed_short_description` warning. The “
   Project home page” line has been moved out of the readme header area and into
   the `== Description ==` section. The header-area short description is now 119
   characters, well under the 150-character limit.

#### 5.1.6

 * Fixed: WPCS `WordPress.WP.I18n.MissingTranslatorsComment` errors in `includes/
   admin/views/dashboard.php`, `n8n-templates.php`, `docs.php` (2x), and `includes/
   Webhook_Dispatcher.php` (2x). Each `__()` / `sprintf( __( ... )` call with placeholders
   now has a `/* translators: ... */` comment on the line directly above it.
 * Fixed: WPCS `WordPress.WP.I18n.UnorderedPlaceholdersText` errors in `includes/
   admin/Ajax_Handler.php` for the two new error messages added in 5.1.4 (`Unknown
   event(s): %s. Allowed: %s.` and `Unknown post type(s): %s. Allowed: %s.`). Placeholders
   reordered to `%1$s / %2$s` and `sprintf()` adjusted to pass arguments in the 
   matching order.
 * Fixed: WPCS `WordPress.PHP.DevelopmentFunctions.error_log_error_log` warnings(
   4x) in `directrelay.php`. The `error_log()` calls in the trace logger, fatal 
   capture, PHP-version-too-old guard, and deactivation hook are now nested inside
   a direct `if ( defined( 'WP_DEBUG' ) && WP_DEBUG )` parent and carry a per-line`
   phpcs:ignore` comment as a belt-and-suspenders fallback. The trace / fatal log
   files (`wp-content/directrelay-trace.log`, `wp-content/uploads/directrelay-error.
   log`) continue to receive every event regardless of `WP_DEBUG`.
 * Fixed: WPCS `readme_parser_warnings_trimmed_short_description` warning. Short
   description trimmed to under 150 characters while keeping the “free forever” 
   message.

#### 5.1.5

 * Fixed: text-domain mismatch flagged by the WordPress Plugin Check tool (WPCS `
   WordPress.WP.I18n.TextDomainMismatch`). The text domain in the plugin header 
   and in every `__()` / `_e()` / `esc_html__()` / `esc_attr__()` / `load_plugin_textdomain()`
   call has been renamed from `directrelay` to `directrelay-automation-bridge-for-
   n8n` to match the WP.org plugin slug.
 * Fixed: 4 `error_log()` calls in `directrelay.php` (trace logger, fatal capture,
   PHP-version-too-old guard) now only fire when `WP_DEBUG` is enabled, resolving
   the WPCS `WordPress.PHP.DevelopmentFunctions.error_log_error_log` warnings while
   keeping the diagnostic log files (`wp-content/directrelay-trace.log`, `wp-content/
   uploads/directrelay-error.log`) intact.

#### 5.1.4

 * Fixed: parse error in `includes/REST/Posts_Controller.php` and `includes/REST/
   Pages_Controller.php` from a leftover `if ( ! true ( $key['id'] ?? 0 ) ) )` dead-
   quota block that was not fully cleaned up during the Pro split. Both `create()`
   methods now proceed straight to `Post_Manager::create()`.
 * Fixed: removed five additional dead-quota blocks left over from the Pro split:`
   Api_Auth::create()` (1-API-key cap), `Ajax_Handler::create_webhook()` and `update_webhook()`(
   max-webhooks cap), `Webhook_Manager::schedule_fire()` (event-type restriction),
   and the `check_and_record_dispatch()` wrapper in `Webhook_Manager::fire()`. The
   free plugin has no usage limits, matching the WP.org Plugin Directory Guidelines.
 * Cleaned: `Webhook_Manager::check_and_record_dispatch()` reduced to a one-line`
   return true;` with a docblock explaining that the dead quota code was removed
   for WP.org compliance. Kept as a stable entry point for any custom code that 
   calls it.

#### 5.1.3

 * Diagnostic: every checkpoint of the plugin load now appends a timestamped line
   to `wp-content/directrelay-trace.log` (and the same line goes to `wp-content/
   uploads/directrelay-error.log` on fatal). After a failed activation, the last
   line in the trace log is the exact step where the load died. The trace also goes
   to the PHP error log via `error_log()` so it shows up in `php_error.log` / `debug.
   log` as well.
 * Diagnostic: if a fatal happens after the shutdown function has been registered,
   the actual error (type, message, file, line) is appended to the same log files.
   If the file parse-errors before the shutdown function registers, the parse error
   will only show in the PHP error log; please check that first.

#### 5.1.2

 * Hardened: PHP version guard rewritten with PHP 5.3+ compatible closure syntax(
   plain `function ()` with no return type and no `static` keyword), so the guard
   itself never parse-errors on old PHP.
 * Hardened: removed the `: void` return type from the internal `directrelay_load_files()`
   definition so the main plugin file is fully backward-compatible at parse time.
 * Hardened: added a `register_shutdown_function` that captures any fatal during
   plugin load and appends the actual error type + message + file + line to `wp-
   content/uploads/directrelay-activation-error.log`. If the activation still fails
   after 5.1.1, this log file is the next place to look — it contains the real cause
   even when WordPress only shows the generic fatal message.

#### 5.1.1

 * Fixed: activation fatal on PHP 7.4 hosts (parse error from `mixed` / `null` /`
   true` standalone return types). DirectRelay now requires PHP 8.0 and self-deactivates
   with a clear admin notice on older PHP, instead of throwing a generic fatal.
 * Fixed: activation hook now wraps the install routine in `try/catch` and shows
   the actual error file + line via `wp_die` if anything goes wrong, so activation
   failures are diagnosable instead of being hidden behind the generic “Plugin could
   not be activated” message.

#### 5.1.0

 * Removed Pro-only REST routes (bulk publish, universal publish, one-shot, approval
   portal, full debugger, Chart.js analytics). They now live in the DirectRelay 
   Pro add-on plugin.
 * Removed Pro-only admin submenus (Approvals, Debugger, AI Guardrails) and their
   views. The Pro plugin re-attaches them.
 * Removed the Chart.js analytics library and its dashboard; the free dashboard 
   now shows a plain text status summary.
 * Removed the Dark Mode CSS rules and toggle. The Pro plugin provides dark mode.
 * Limited the n8n templates page to one free starter template. Additional templates
   are provided by the Pro plugin via the `directrelay_pro_templates` filter.
 * Added `directrelay_pro_register_routes`, `directrelay_pro_register_admin`, `directrelay_pro_seo_update`,`
   directrelay_pro_guardrails_check`, `directrelay_pro_notification`, `directrelay_pro_debug_log`,`
   directrelay_pro_dashboard_data`, `directrelay_pro_templates`, and `directrelay_pro_body_class`
   extension hooks.
 * Added basic email notification on webhook dispatch (admin email, opt-in via plugin
   Settings).
 * SEO write endpoint now returns 402 Payment Required with a stable `directrelay_pro_required`
   error code.
 * Rebranded the plugin from “CyberNode” to “DirectRelay” across all files, namespaces,
   constants, and the readme header.

#### 5.0.0

 * Initial WordPress.org release as DirectRelay Automation Bridge for n8n.
 * Added full REST API routes for Posts, Pages, Media, Taxonomies, and Custom Meta.
 * Added SEO metadata read support for Rank Math and Yoast SEO.
 * Added HMAC-SHA256 signed outgoing webhooks with automatic retry logic.
 * Added a self-hosted OpenAPI 3.0 specification endpoint.
 * Added a sliding-window rate limiter for DoS protection.
 * Added the Compatibility checker for permalinks, REST API, SSL, and SEO plugin
   detection.

## Meta

 *  Version **5.1.31**
 *  Last updated **12 hours ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.3 or higher **
 *  Tested up to **7.1.1**
 *  PHP version ** 8.0 or higher **
 * Tags
 * [api](https://wordpress.org/plugins/tags/api/)[automation](https://wordpress.org/plugins/tags/automation/)
   [n8n](https://wordpress.org/plugins/tags/n8n/)[rest](https://wordpress.org/plugins/tags/rest/)
   [seo](https://wordpress.org/plugins/tags/seo/)
 *  [Advanced View](https://wordpress.org/plugins/directrelay-automation-bridge-for-n8n/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/directrelay-automation-bridge-for-n8n/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/directrelay-automation-bridge-for-n8n/reviews/)

## Contributors

 *   [ N4nion ](https://profiles.wordpress.org/n4nion/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/directrelay-automation-bridge-for-n8n/)