An incoming webhook gives an external service a public URL that can start a selected AI Agent Workflows workflow with data from an HTTP POST request. You can configure a signing secret and an IP allow-list for each endpoint. The linked workflow must be active before the endpoint can start it.
Before you begin
- Create the workflow you want to start and activate it.
- Decide whether the caller can sign requests with an HMAC secret. Use signing for endpoints that receive data from an external service.
- If the caller uses a stable source IP, prepare the exact IP address or supported IPv4 CIDR range for the allow-list.
Create the webhook
- In the WordPress dashboard, open Agent Workflows → Webhooks.
- Select Add New. The Add New Webhook form opens.
- Under Workflow, select the workflow that should receive the event. Draft or paused workflows are listed as inactive and must be activated before the endpoint can be called successfully.
- Configure Signing secret as described below.
- Optionally add permitted addresses under IP allow-list, one entry per line.
- Select Create Webhook. The plugin saves the endpoint and returns to the Webhooks list.
- Find the new row. Select its public URL or choose Edit to open the endpoint details. Copy the displayed Public URL (POST) and keep it private.
Screenshot to add: [Add New Webhook configuration form]
Screenshot to add: [Edit Webhook form and public POST URL]
Configure request signing
The Signing secret field is optional only when site settings allow unsigned webhooks. If a secret is configured, every request must include a matching signature. The plugin does not generate the secret for you, so create a strong random value and store it securely in both the webhook configuration and the calling service.
The required header is X-dragaiw-Signature. Its value must be sha256= followed by the hexadecimal HMAC-SHA256 digest of the exact raw request body, using the signing secret. Do not parse and re-serialize the JSON between calculating the signature and sending the request; even whitespace changes the signed bytes.
To require signing across all endpoints, open Agent Workflows → Settings → Advanced, enable Require a signing secret on every inbound webhook, and select Save Advanced Settings. When this setting is enabled, an endpoint cannot be created or called without a configured secret. A secret configured on an individual webhook also requires signing even when the site-wide setting is off.
Screenshot to add: [Advanced settings — Webhook signing]
Limit requests by IP address
In IP allow-list, enter one exact IPv4 or IPv6 address per line. IPv4 CIDR ranges such as 203.0.113.0/24 are also supported. Leave the field empty to allow requests from any source IP. IPv6 CIDR ranges are not supported by the current implementation.
The endpoint checks the caller address from the web server’s REMOTE_ADDR value. It does not trust X-Forwarded-For or similar request headers. If the site is behind a reverse proxy, configure the server or trusted proxy to set the real client address correctly before relying on the allow-list.
Send a test POST request
The plugin does not provide a separate test button for incoming webhooks. You can send a small request from a terminal or from the external service that will call the endpoint. Replace the example URL and secret with your own values. This sample uses a JSON object with test-only data.
WEBHOOK_URL='PASTE_YOUR_PUBLIC_URL_HERE'
WEBHOOK_SECRET='REPLACE_WITH_YOUR_SIGNING_SECRET'
BODY='{"event":"webhook-test","source":"manual-test","record_id":"demo-001"}'
SIGNATURE=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | awk '{print $NF}')
curl -i -X POST "$WEBHOOK_URL" \
-H 'Content-Type: application/json' \
-H "X-dragaiw-Signature: sha256=$SIGNATURE" \
--data-binary "$BODY"
The signature must be calculated from the same exact bytes sent in BODY. If the webhook has no signing secret and the site-wide requirement is disabled, omit the signature header. Do not use real customer or payment data in an initial test.
Understand the payload
For a valid JSON object or array, the plugin decodes the request body and stores it under the webhook trigger payload’s body key. The payload also includes source with the value webhook and the detected client_ip. If the request body is not valid JSON or does not decode to an object or array, the plugin keeps the original text under body.raw. Send JSON when you want structured fields to be available to later workflow nodes.
Check the run result
Open Agent Workflows → Runs to find the run created by the request. Use the returned run_id to match the request with the recorded run. With background execution enabled, the endpoint queues the run and normally returns HTTP 202 with a queued status. When background execution is disabled, it runs the workflow during the request and returns HTTP 200 with the run status. A successful HTTP response does not by itself mean every workflow node succeeded; inspect the run details.
Screenshot to add: [Workflow run details for an incoming webhook]
Troubleshoot rejected requests
| Response | Likely cause and next step |
|---|---|
401 — Invalid webhook signature. | Check the secret, header spelling, sha256= prefix, and that the digest was calculated from the exact raw request body. |
403 — Request IP is not allowed for this webhook. | Confirm the caller’s actual server IP is on the allow-list. Check reverse-proxy configuration if the detected address is unexpected. |
403 — Signing is required but no secret is configured. | Set a secret on the webhook and configure the caller to sign requests. |
404 — Webhook not found. | Copy the complete public URL again and confirm the endpoint still exists. |
409 — The webhook is not linked to a workflow or the linked workflow is not active. | Edit the webhook to select an existing workflow, then activate that workflow. |
429 — Rate limit exceeded. | The endpoint has received 60 requests from the same source IP for this webhook within 60 seconds. Wait before retrying and check for repeated caller retries. |
500 — The workflow could not be started or the signature could not be verified. | Check the webhook’s saved secret and WordPress/PHP logs, then try again after correcting the underlying issue. |
Edit or remove an endpoint
From Agent Workflows → Webhooks, select the endpoint’s public URL or Edit to change its workflow, signing secret, or IP allow-list. On the edit form, leave Signing secret blank to keep the current value; enter a new value to rotate it. The current secret is shown only in masked form. Select Remove signing secret to clear it when site settings do not require signing.
To stop using an endpoint permanently, select Delete on its row or select multiple rows and use the bulk Delete action. Deleting the webhook removes that endpoint; there is no separate pause or disable control. Update the external service so it no longer sends requests to a deleted URL.
Requests are public and the implementation does not add a timestamp or nonce to the HMAC scheme, so signing alone does not provide replay protection. Keep secrets private, use an IP allow-list where practical, monitor the Runs screen, and do not assume that a public URL or rate limit prevents every form of abuse.