---
title: "Plugin Changelog — Webhook Actions"
description: "Full release history for Webhook Actions, the free WordPress webhook plugin by Flow Systems. Every fix, feature, and improvement since v1.0.0 — updated with each release."
url: "https://wpwebhooks.org/changelog/"
---

[WP Webhooks](https://wpwebhooks.org/)/ Changelog

/Plugin

# Changelog

Every release of Webhook Actions — the free WordPress plugin.

## v2.2.2 2026-07-18

-   → Fixed Build with AI can now discover and propose Gravity Forms' gform\_after\_submission trigger — some plugin hooks are fired through a wrapper function instead of a direct WordPress do\_action() call, which made them invisible to hook discovery, so the AI would fall back to a less suitable trigger
-   → Improved hook discovery now cross-checks WordPress's registered filters so a filter can never be mistakenly proposed as a webhook trigger, avoiding interference with the filter's normal behavior

## v2.2.1 2026-07-17

-   → Fixed Build with AI no longer loses a turn when the AI provider returns a JSON reply cut off just before its final closing brace (seen in the field with Gemini's JSON mode) — a reply missing only its closing brackets is now completed and parsed, while a reply that lost real content is still rejected rather than guessed at
-   → Improved the AI Dev Trace now records the provider's reported finish reason for every model call, so a truncated reply is distinguishable from a token-limit stop at a glance

## v2.2.0 2026-07-14

-   → New the AI Builder reads your site's own REST API contracts before building an internal automation (new get\_rest\_route\_schema read), so required fields like a user's password are handled with a Code Glue snippet — or called out honestly — instead of guessed
-   → New test deliveries proposed in a plan now pause for your confirmation with a clear warning when they will create or modify real data (e.g. actually create a WordPress user)
-   → New after a build finishes you can flip the webhook between background and synchronous delivery right in the chat — and the AI now recommends a delivery mode based on real evidence that your queue is draining
-   → New plan review shows the exact PHP code a Code Glue snippet step will install, so you approve the code, not just a summary
-   → New assistant replies stream in with a word-by-word reveal
-   → Improved endpoint probes only ask for confirmation on destructive methods (PUT/PATCH/DELETE); confirming a probe no longer self-rejects
-   → Fixed the AI prompt no longer claims Pro Code Glue is available when the Pro plugin isn't actually running — and any proposed plan steps this site can't run are surfaced as a notice instead of being silently dropped from the plan
-   → Dev: deliveries to your own site's REST API work on local environments with self-signed certificates (WP\_ENVIRONMENT\_TYPE=local, own host only — external endpoints always keep TLS verification)

## v2.1.3 2026-07-09

-   → Fixed the AI Builder no longer creates duplicate webhooks or Application Password credentials when a model re-sends a plan it already applied — steps that were already built are recognised and reused instead of run again
-   → Improved when your chosen AI model can't respond and the build falls back to another model or provider, the AI Builder now shows a notice (with the reason) so you can switch models, instead of quietly answering from a different one
-   → Fixed a WP Application Password provisioned during a build is now automatically attached to the webhook that needs it, instead of being created but left unassigned

## v2.1.2 2026-07-08

-   → Fixed the AI Builder no longer loses a turn when the AI provider returns slightly malformed JSON — a stray trailing brace, a trailing comma, or an unescaped line break is now repaired and parsed instead of failing silently
-   → Improved for automations that call this site's own WordPress REST API, the AI Builder proposes the full plan and lets you pick or create the auth credential right in the plan, instead of asking for it in chat
-   → New one-click "Create a WP Application Password for me" on the credential step (and a matching AI plan step) — it mints an Application Password for the current administrator and stores it in the vault as a ready-to-use Basic credential named "WP REST API (internal)"
-   → Improved the AI Builder now knows webhooks carry no code field, and points you to Code Glue (with Pro) for computed values or to the WordPress REST API for code-free internal automations

## v2.1.1 2026-07-07

-   → Improved AI Builder chat shows live progress while the agent gathers site data — each read round appears as it runs instead of a silent spinner
-   → Fixed a failed AI provider call mid-conversation no longer loses the turn — everything gathered so far is saved, and retrying resumes from there without re-running the reads
-   → Fixed the agent now detects captured example payloads with no usable fields (captured by older plugin versions), shows what the capture contains, and asks for a fresh test event instead of inventing field paths
-   → Fixed AI test deliveries now run pre-dispatch Code Glue snippets (with Pro), matching real dispatches, and report whether a snippet ran
-   → Improved the trigger-catalog read supports search with capped results, and older read results are trimmed from the model's context — faster responses and fewer provider timeouts
-   → Improved AI provider requests allow up to 120 seconds (new `fswa_ai_http_timeout` filter) instead of timing out at 60 on large conversations
-   → New copy-to-clipboard buttons in the AI Dev Trace panel — full trace entry as JSON, system prompt, messages, raw request and response
-   → Fixed AI trace logging no longer stops silently when the day's log file was created by a CLI session

## v2.1.0 2026-07-07

-   → Improved **Agentic AI Builder** — the agent can now read live site data mid-conversation (webhooks, logs, captured payloads, credential names) before proposing a plan, instead of guessing
-   → Improved AI responses are requested as raw JSON (Gemini, OpenAI) and conversations replay the model's exact envelopes — fixes plans failing to parse when the model wrapped them in prose or code fences
-   → Fixed multi-step snippet plans (with Pro) — snippet ids created in one step now resolve in the next, and stage values like `pre_dispatch` are accepted
-   → Fixed AI test deliveries now apply the stored field mapping, matching real dispatches
-   → Improved the AI ability catalog documents exact enum values and the full field-mapping format, and plans may use `{{site.url}}` / `{{site.rest_url}}` placeholders for this site's own REST API
-   → Improved the system prompt includes the site's home and REST URLs, so internal automations (webhooks targeting this site's own WP REST API) work without asking for the URL

## v2.0.0 2026-07-06

-   → New **Build with AI** — an in-admin AI agent that builds webhook integrations and automations for you. Describe the outcome in chat; the agent inspects your site, proposes an editable plan, and on approval builds and tests the webhooks, mappings, conditions, and chains. Works plan-first with hybrid confirmation: new webhooks are created disabled, and going live / deleting / editing a live webhook requires explicit confirmation. One-click undo of the last build
-   → New **LLM transport auto-detection** — uses the WordPress 7.0 AI Client (`wp_ai_client_prompt()`) when a provider is configured (no API key stored), otherwise falls back to your own Anthropic, OpenAI, or Google API key stored encrypted in the Credentials Vault, with a curated model picker and automatic cross-provider fallback on rate limits
-   → New **WordPress Abilities API integration** — the plugin's operations (list/create/update webhooks, set mapping/conditions, test dispatch, probe endpoint, manage credentials, build chains) are registered as `flowsystems-webhook-actions/*` abilities, so external AI tools can discover and invoke the same toolset via REST and the MCP Adapter
-   → New **Guarded endpoint probe** — the agent can make a safe test call to a target API to validate a credential or endpoint before wiring a webhook, with an SSRF guard, rate limiting, response-size cap, and full secret redaction
-   → Developer: New `fswa_ability_definitions`, `fswa_ability_permitted`, and `fswa_ai_transport` filters

## v1.16.0 2026-06-22

-   → New **Full internationalization** — the entire admin interface (every screen, dialog, and inline message) and all server-side strings are now translatable. The plugin is fully translatable and compatible with WPML and Polylang String Translation, and free locales can also be contributed through translate.wordpress.org
-   → New **Polish (pl\_PL), Simplified Chinese (zh\_CN), and Dutch (nl\_NL)** translations bundled out of the box
-   → Improved The admin bundle now uses a stable, hash-free filename with handle-based script-translation loading, so JavaScript translations resolve reliably across plugin updates
-   → Developer: Translation template (`.pot`) regenerated to cover all PHP and JavaScript strings (the Vue SPA strings are extracted from source, since `wp i18n make-pot` cannot read `.vue` files). Add a language by dropping a locale `.po`/`.mo`/`.json` set into `languages/`

## v1.15.0 2026-06-07

-   → New **Credentials Vault** — store reusable authentication secrets (Bearer token, Basic auth, API key, custom header) once, encrypted at rest with AES-256-GCM, and reference them from webhooks via a saved credential instead of pasting a raw Authorization header. Secrets are **write-only** over the REST API — never returned to any caller, only a masked hint (e.g. `Bearer ****1234`) — and are decrypted only at dispatch time to build the outgoing header
-   → New **`agent` API token scope** — grants full write access (create/update/delete webhooks and credentials) for AI assistants, while never being able to reveal a webhook's `auth_header` or any vault secret. Groundwork for safe AI-driven webhook management
-   → New **`FSWA_SECRET_KEY` wp-config constant** (optional hardening) — by default the encryption key is auto-generated and stored in the database (zero-config, survives WordPress salt rotation); define `FSWA_SECRET_KEY` to move it out of the database. Adding it never breaks existing credentials (decryption falls back to the old key), and an in-app one-click migration re-encrypts everything with the new key and then deletes the database key
-   → New **"Save to vault"** action on the webhook form — migrate an existing manual Authorization header into the encrypted vault in one step (`Bearer …` is detected automatically; anything else is stored as a custom Authorization value)
-   → Improved Resolved Authorization and custom auth headers are now redacted (`[redacted]`) when persisted to delivery logs, so a decrypted secret never lands in the log store
-   → Developer: New REST endpoints under `/fswa/v1/credentials` — list/create/update/delete (all `full`/`agent` scope), plus `GET /credentials/key-status` and `POST /credentials/reencrypt`. Webhooks accept an `auth_credential_id` reference (takes precedence over the legacy `auth_header`, which still works)
-   → DB adds the `fswa_credentials` table and an `auth_credential_id` column on `fswa_webhooks`; idempotent, safe to run on existing installs

## v1.14.1 2026-06-05

-   → Fixed "Get Pro" links updated to `/pricing/` page
-   → Improved Admin Menu moved to its own settings card
-   → Improved External Cron description expanded in README

## v1.14.0 2026-06-03

-   → New **Activity History** — persistent audit log of every admin and API-token action across webhooks, tokens, settings, logs, queue, schemas, chains, and cron. Each entry records the actor (session user or API token with a name hint), the action type, a structured context diff (old → new values for updates), and a timestamp. Designed to trace automated and AI-assisted changes end-to-end
-   → New **AI prompt and reasoning capture** — REST requests carrying `X-FSWA-Prompt` or `X-FSWA-Reason` headers have those values stored in the activity log context and surfaced in the Activity view as a highlighted card above the change diff; intended for AI agents that perform admin actions via API tokens
-   → New **External Cron page** \*(Pro)\* — dedicated admin page for managing the external cron trigger: enable/disable toggle, mode selector, configurable interval and batch-size sliders, a live heartbeat chart (line + bar combo), monitor status bar, and an alert banner when the last ping failed or is stale
-   → New `fswa_cron_token_regenerated` action hook — fires after the cron secret is regenerated, allowing integrations (e.g. Pro Uptime Kuma sync) to update their stored monitor URL
-   → Fixed created and deleted activity log entries for webhooks and tokens now include the full entity data (name, URL, scope, etc.) in context instead of an empty object
-   → Fixed webhook toggle events now correctly capture old and new `is_enabled` state; webhook, settings, and schema update events capture a full old/new diff
-   → Fixed chain and chain-link CRUD actions (create, update, delete, link add/remove) are now covered by Activity History
-   → Improved Snippets (Pro) added to the Activity History filter list; Activity tab repositioned after External Cron in the navigation
-   → DB adds `fswa_activity_logs` table; idempotent, safe to run on existing installs

## v1.13.1 2026-05-21

-   → Fixed Replay and Retry buttons on the single-webhook logs page (`#/webhooks/:id/logs`) did nothing — the events emitted by the table were never handled. Both the row button and the Log Details panel button now work correctly, including the "Execute Now" flow and the replay success dialog
-   → Fixed bumped tested-up-to WordPress version to 7.0

## v1.13.0 2026-05-18

-   → New **Webhook Chains** — a webhook completing successfully (2xx) can now trigger one or more downstream webhooks. Chains are first-class entities with names and links; each chained webhook receives the upstream response body, sent payload, and pre-mapping original payload as its starting `args`, so the next step can map fields off the previous step's response (e.g. capture a HubSpot deal ID and pass it to a Create Line Items webhook). Replaces ad-hoc `wp_remote_post` calls in post-dispatch snippets with proper webhooks that get logs, retries, conditions, headers, and URL templates
-   → New Triggers section on Edit Webhook now offers a "Use other Webhooks as triggers" toggle. When enabled the webhook is wired as a chain target — pick an existing chain or create a new one, then select which upstream webhooks should fire it (with a search box for filtering long lists). Defaults to synchronous execution so the response is available immediately
-   → New Webhooks list view groups webhooks by chain with a left accent border and chain icon; a webhook involved in multiple chains is rendered in each group. An "Unchained" section holds webhooks with no chain involvement
-   → New Chain group headers now have inline **Rename** and **Delete** buttons. Deleting a chain shows an impact callout listing which downstream webhooks would become orphans, and a chain is automatically removed when its last link is deleted
-   → New Orphan badge — any webhook left with no triggers (after a chain or link deletion, for instance) shows a destructive-styled broken-link icon and "No trigger assigned" label so it stays visible and editable in the list
-   → New Deleting a webhook involved in any chain shows an enhanced confirmation modal listing the affected chains and downstream impact, then cascade-removes the chain links and their synthetic trigger rows
-   → New Logs and Queue views render chain-link triggers as human-readable pills (`Chain name ← Source webhook`) instead of the raw `fswa_chain_link:N` synthetic name, and gain a "Filter by chain" dropdown that narrows the list to deliveries triggered by a specific chain
-   → New REST endpoints `/fswa/v1/chains` (CRUD) and `/fswa/v1/chains/{id}/links` (manage source→target edges). Cycles are rejected at save time across all chains. Both `/logs` and `/queue` list endpoints now accept a `chain_id` query parameter
-   → Fixed `X-Event-Id` and `X-Event-Timestamp` request headers were emitted empty when Payload Mapping or Code Glue pre-dispatch reshaped the payload and dropped the `event` block. Headers now resolve from the log row first (single source of truth) and only fall back to the payload if needed
-   → Fixed payload preview in the Payload Mapping editor could break the page layout when a captured payload string contained HTML (e.g. a chain-link trigger carrying an upstream HTML response body in `args.0.response.raw_body`). String values are now properly HTML-escaped before being injected into the highlighted JSON preview — also closes a stored-XSS surface in the admin UI
-   → DB new `fswa_chains` and `fswa_chain_links` tables; idempotent, safe to run on existing installs

## v1.12.2 2026-05-14

-   → Fixed "Queue appears stuck" health banner staying visible when delivery logs were left in `pending` state with no live queue row (e.g. legacy rows from older queue-status semantics, or worker crashes between updating queue and log state); the queue processor now reconciles such orphaned pending logs on every run and marks them `permanently_failed`
-   → Improved trigger conditions UI — renamed the "Evaluate against" toggle to "Evaluate conditions against" and added an inline info tooltip explaining the Original (pre-mapping) vs Transformed (post-mapping) choice
-   → Removed misleading Pro upgrade badge from the conditions evaluate-against toggle — choosing between original and transformed payload for conditions has always been a free-plan feature

## v1.12.1 2026-05-12

-   → Docs corrected README to reflect that type casting (in both payload mapping and conditions) is a free-plan feature; removed misleading Pro markers
-   → Docs added WooCommerce → n8n step-by-step example showing conditional dispatch wired up via a Claude Code agent
-   → Docs reformatted `fswa_webhook_url` PHP code sample so it renders as a single code block on the wordpress.org plugin page
-   → No code changes

## v1.12.0 2026-05-12

-   → New `fswa_webhook_payload` filter — Pro-extensible enrichment of the outgoing payload before dispatch; receives the mapped payload, webhook id, trigger name, and pre-mapping original payload
-   → New `fswa_glue_post_dispatch` action — fires after every delivery with response code/body, mapped payload, webhook, and original pre-mapping payload; intended for Pro post-dispatch snippets
-   → New `fswa_webhook_url` filter — Pro-extensible URL template expansion; passes the URL, post-glue payload, webhook, trigger, and original pre-mapping payload as fallback for dot-notation token resolution
-   → New per-trigger `conditions_evaluate_on` setting (original / transformed) — choose whether conditions evaluate against the pre-mapping payload or the post-mapping/post-glue payload; segmented toggle in the trigger schema panel
-   → New dual-resolution for custom headers and URL parameters — when a dot-notation path resolves to null in the post-glue payload, falls back to the pre-mapping original payload; matches existing condition resolution semantics
-   → New collapsible Original Payload section in the Mapping editor — inspect the pre-glue/pre-mapping payload while authoring field mappings
-   → Improved `object_contains` operator — also matches when the value is present at the current array level, not only nested; works for array-typed WooCommerce fields like `meta_data` and `line_items`
-   → Improved delivery log writes — `request_payload`, `original_payload`, and `mapping_applied` are now refreshed after the `fswa_webhook_payload` filter mutates the payload
-   → Fixed condition evaluation order — re-evaluates conditions after Code Glue pre-dispatch when `conditions_evaluate_on` is `transformed`
-   → Fixed pre-glue filter application in synchronous mode — applied exactly once during the inline attempt instead of once before enqueue and again at send

## v1.11.0 2026-05-06

-   → New `array_contains` condition operator — checks whether an array field contains a specified value; works with flat arrays and arrays of objects
-   → New `object_contains` condition operator — checks whether an object field contains a specified key (optionally filtered to a specific property within nested objects using a `key=` parameter)
-   → New `stringify` type cast — JSON-encodes array and object field values into a string before comparison, enabling string-based operators on complex nested structures
-   → Improved FieldSelector — split navigate and select actions; added a dedicated "+" button to select non-leaf fields (arrays and objects) directly without drilling further into children
-   → Improved ConditionsEditor layout — responsive three-row design on small screens (field + delete on top row, cast + operator on second row, value on third); `object_contains` exposes an inline property name input when a key filter is needed
-   → Delivery log detail messages now include the property key when `object_contains` is matched against a specific property

## v1.10.0 2026-05-03

-   → New per-webhook synchronous execution mode — when enabled, the webhook fires inline during the WordPress request that triggers it, bypassing the queue; a warning dialog explains the performance impact before enabling; dismissal can be stored permanently per-browser
-   → First synchronous attempt runs blocking in the current request; retryable failures (5xx, transport errors) automatically fall back to the async queue starting at attempt 2 with standard exponential backoff; non-retryable failures (4xx) are marked permanently failed immediately
-   → New sync execution toggle to the Webhooks list view — enable or disable per webhook without opening the edit screen
-   → New Request Headers and Query Parameters sections to delivery log details — inspect the exact headers and URL parameters sent with each delivery
-   → New collapsible Request Payload and Original Payload sections in delivery log details — collapse state is persisted in browser storage so the panel opens in the same state on next visit
-   → Fixed GET and DELETE webhooks not including custom headers or URL parameters in deliveries
-   → New replay support for skipped (condition-failed) log entries — re-evaluate a previously skipped event after changing the webhook's conditions

## v1.9.0 2026-05-03

-   → New configurable HTTP method per webhook — choose GET, POST, PUT, PATCH, or DELETE (default: POST)
-   → New custom request headers per webhook — define key/value pairs sent with every delivery; values support dot-notation paths resolved against the outgoing payload
-   → New URL query parameters per webhook — appended to the endpoint URL; for GET and DELETE requests, query params are the primary payload transport (no body); a full `?payload=` fallback is used when no params are configured
-   → New `fswa_capture_payload` filter — modify or enrich the payload stored as the captured example without affecting what is dispatched; designed for Pro extensions and custom PHP snippets
-   → New `fswa_webhook_response` action — fires after every HTTP response is received per webhook; intended for Pro extensions to run custom logic against the response (parse body, trigger follow-up actions, store data)
-   → New `request_headers` and `request_url` columns to delivery logs — the exact headers sent and the fully resolved URL (with query params applied) are now stored and visible in the delivery log
-   → Improved test webhook drawer — defaults to "Captured + Mapping" payload source; result panel now shows HTTP method, fully resolved endpoint URL, sent headers, and request body

## v1.8.0 2026-04-28

-   → New type casting in Conditions — cast field values to number, string, or boolean before comparison; enables greater than / less than on numeric strings (e.g. WooCommerce price "100.50")
-   → New type casting in Payload Mapping — cast field values before sending to external APIs
-   → New `X-Webhook-Id` request header — sent with every delivery; carries the webhook's stable UUID so downstream systems can identify which webhook configuration triggered the request when multiple webhooks share the same endpoint
-   → Fixed test webhook result label — now reflects actual HTTP status: 2xx = Success, 3xx = Redirect, 4xx = Client Error, 5xx = Server Error (previously all completed deliveries showed green "Success")

## v1.7.0 2026-04-27

-   → New "Test Webhook" delivery with run-now and queue modes — test webhook delivery without triggering real WordPress events
-   → New conditional webhook dispatch — filter events by payload field values before dispatch; free plan includes one condition with AND match
-   → New field selector with live preview in the Conditions editor to build conditions from real example payloads
-   → Fixed attempt history timestamps displayed in browser local time
-   → Renamed plugin to "Webhook Actions by Flow Systems"
-   → New Webhook Actions Pro integration tab for license management

## v1.6.2 2026-04-05

-   → Fixed graceful handling of 409 responses when a queue job was already completed in a background process
-   → Fixed mapping editor not supporting dot-containing keys (e.g. Gravity Forms sub-field IDs like `6.1`)

## v1.6.1 2026-03-28

-   → Fixed schema API endpoints for triggers containing forward slashes (e.g. `ivyforms/form/before_submission`) returning 404 on Apache — admin now uses double-encoding to pass through Apache's encoded-slash restriction

## v1.6.0 2026-03-28

-   → New built-in IvyForms integration — automatically normalizes IvyForms field objects and enriches submission payloads for `ivyforms/form/before_submission` and `ivyforms/form/after_submission` hooks
-   → New IntegrationLoader to centralize third-party integration registration
-   → Fixed forward slashes not being recognized in hook names during dynamic trigger discovery
-   → Fixed percent-encoded slashes in schemas REST route trigger param not being decoded correctly
-   → Fixed trigger name not being URL-encoded when building schemas API requests from the admin UI

## v1.5.0 2026-03-23

-   → New built-in CF7 to webhook integration — automatically sends CF7 submissions as structured webhook payloads (form id, title, fields, meta, uploaded files)
-   → New `fswa_normalize_object` filter for custom third-party object normalization
-   → New `get_properties()` fallback in payload normalization to handle objects with private or protected properties
-   → Improved hook registration to capture all hook arguments by default (PHP\_INT\_MAX accepted\_args)

## v1.4.0 2026-03-22

-   → New Action Scheduler support for queue processing (auto-detected, no configuration required)
-   → Automatic migration from WP-Cron to Action Scheduler when available
-   → New option to move admin menu under Tools for cleaner dashboard navigation
-   → New dynamic trigger discovery via static PHP source scan
-   → Reduced triggers API responses size
-   → Fixed input focus styles in admin forms

## v1.3.2 2026-03-15

-   → Fixed `auth_header` field being exposed to API tokens without `full` scope — read and operational tokens now receive a permission notice instead

## v1.3.1 2026-03-15

-   → Fixed log details dialog showing error message from the first attempt instead of the most recent one
-   → New \[REST API Reference\](https://wpwebhooks.org/webhook-wordpress-plugin-api/) link to the plugin description

## v1.3.0 2026-03-15

-   → New API token authentication for the REST API — create tokens with `read`, `operational`, or `full` scope; tokens are SHA-256 hashed at rest and accepted via `X-FSWA-Token` header, `Authorization: Bearer`, or `?api_token=` query param
-   → New token expiry support with optional `expires_at`; expired tokens are rejected at auth time and visually flagged in the admin panel
-   → New token rotation — issues a new secret while preserving all other token fields; optionally updates expiry in the same request; revived expired tokens auto-extend to +30 days by default
-   → New `PATCH /tokens/{id}` endpoint for updating `expires_at` independently of rotation
-   → New `fswa_api_tokens` database table (migration 1.3.0)
-   → Applied scope-based dual auth (`manage_options` session OR valid token) to all existing REST controllers: `read` for GET endpoints, `operational` for toggle/retry/replay, `full` for create/update/delete
-   → Fixed all admin UI date displays (logs, queue, schema panel) to show times in the user's local timezone instead of raw UTC
-   → Fixed date range filters (logs, queue) to correctly convert local picker values to UTC before querying
-   → Improved log details panel — error message, response body, HTTP code, and duration now reflect the most recent attempt history entry rather than the top-level log fields

## v1.2.1 2026-03-07

-   → Fixed retry returning 500 when a log has multiple queue jobs (replay + original) — `findByLogId` now returns the most recent job via `ORDER BY id DESC`
-   → Fixed `forceRetry` rejecting jobs with status `failed` — restored `failed` to the allowed status list alongside `pending` and `permanently_failed`

## v1.2.0 2026-03-07

-   → New persistent delivery stats table (`fswa_stats`) for long-term aggregation
-   → New replay button for successful log entries
-   → New "Execute Now" button in replay dialog with auto-open log details
-   → New full attempt history with response body, accordion UI, and next attempt countdown
-   → Replaced browser `confirm()` dialogs with modal confirmations
-   → Fixed queue stats — removed stale `failed` status, added `permanently_failed`
-   → Fixed retry eligibility check to use log status instead of queue job status
-   → Fixed "Execute Now" button visibility to only show for pending jobs

## v1.1.1 2026-03-01

-   → Fixed `permanently_failed` entries being excluded from total and error delivery statistics in `getStats()`, `getAllTimeStats()`, and `LogArchiver::aggregateStatsBeforeDeletion()`

## v1.1.0 2026-02-28

-   → New event identity: each trigger dispatch generates a shared UUID and timestamp sent as `X-Event-Id` / `X-Event-Timestamp` headers and embedded in the payload under `event.{id,timestamp,version}`
-   → New smart retry routing: 5xx and 429 responses trigger an automatic retry with exponential backoff; 4xx and 3xx responses are immediately marked as permanently failed
-   → New `permanently_failed` status for non-retryable delivery failures
-   → New attempt history: each delivery attempt is recorded as a JSON array on the log entry, visible in the admin timeline view
-   → New per-log retry and bulk retry REST endpoints (`POST /logs/{id}/retry`, `POST /logs/bulk-retry`)
-   → New `event_uuid` and `target_url` filter parameters to logs and queue REST endpoints
-   → New date range filtering (`date_from`, `date_to`) to logs and queue list views with a shadcn-style calendar date/time picker
-   → New health observability metrics: average attempts per event, oldest pending age, queue stuck detection, WP-Cron-only warning
-   → New `queue.log_id` column linking queue jobs to their log entries
-   → Updated admin UI: permanently failed badge, attempt timeline, per-row retry button, bulk retry, observability warning banners, new filter inputs
-   → Updated footer with a review prompt linking to WordPress.org

## v1.0.1 2026-02-18

-   → Fixed preview freezing when mapping fields from objects with numeric string keys (e.g. WooCommerce line\_items)
-   → Fixed orphaned pending log entries caused by logPending() silently failing — queue jobs now carry mapping metadata and recover a proper log entry if the original ID was lost
-   → Enhanced normalizeValue to handle Closure, DateTimeInterface, and Traversable types
-   → Removed unnecessary WooCommerce hook patterns from trigger exclusions
-   → Improved log details display with word break for long trigger names and dates

## v1.0.0 2026-02-16

-   → Initial release
-   → Webhook dispatching from WordPress actions
-   → Background processing with retry mechanism
-   → Configurable webhook payloads
-   → Logging of webhook deliveries

/Ready

## Your next automation is  
one sentence away.

[Install Plugin→](https://wordpress.org/plugins/flowsystems-webhook-actions/) [See the Plugin →](https://wpwebhooks.org/wordpress-webhook-plugin/)

$ wp plugin install flowsystems-webhook-actions --activate

## Structured data

```json
{"@context":"https://schema.org","@type":"WebPage","name":"Plugin Changelog — Webhook Actions","description":"Full release history for Webhook Actions, the free WordPress webhook plugin by Flow Systems.","url":"https://wpwebhooks.org/changelog/","isPartOf":{"@type":"WebSite","name":"WP Webhooks","url":"https://wpwebhooks.org"},"about":{"@type":"SoftwareApplication","name":"Webhook Actions","url":"https://wpwebhooks.org/wordpress-webhook-plugin/"}}
```
