Founding offer — 25% off applied automatically at checkout. Ends 1 November 2026 or after our first 30 orders. See pricing →
Skip to document content
Guide

Outbound Acknowledgement Webhooks (Pro)

9 min read 4 views
Version
1.0
Last Version Update
October 4, 2026
Effective From
October 4, 2026
Review Cycle
Annual
Next Review Due
October 2027

Outbound Acknowledgement Webhooks (Pro)

This feature requires the Dantian Policy Management Pro add-on.

The webhook feature sends a signed notification to a URL you choose when acknowledgement and document events happen — most commonly, every time a staff member acknowledges a document. Use this to integrate these events with your HR system, audit management tool, Slack workspace, or any other system that accepts webhooks.

Webhooks need an active Pro licence.


What is a webhook?

A webhook is an outbound HTTP POST request your site sends to a URL you specify when a specific event occurs. Unlike an API you call manually, webhooks fire automatically in response to events — in this case, document acknowledgements and document changes.


What triggers a webhook

One destination URL receives four kinds of event. Each can be switched on or off individually under Webhook Events, and all four are on by default once you save a URL:

  • Acknowledgement recorded — a staff member acknowledges a document. Names the acknowledging user.
  • Version approved — a new document version is approved. Names the approver.
  • Version rejected — a new document version is rejected. Names no individual.
  • Document published — a document is published for the first time (or republished from another status). Names the document author.

Note that the approval and publication events carry the name of a different person from the acknowledgement event. Check each event’s subject before enabling it for a third-party processor.


What the webhook payload contains

Each request sends a JSON body. The acknowledgement payload looks like this:

{
  "user_id": 42,
  "document_id": 101,
  "name": "Jane Smith",
  "role": "subscriber",
  "policy": "Code of Conduct (v2.1)",
  "date_signed": "2026-05-22T09:14:00+10:00"
}
  • policy is the document title, with the acknowledged version number in brackets when the document is versioned.
  • role is the user’s primary WordPress role.
  • date_signed is the time of the acknowledgement in ISO 8601 format, in your site’s timezone.

The other events send these fields:

Event Fields
Version approved event (version_approved), document_id, document (title), version, change_type, description, approved_by (approver’s display name), date
Version rejected event (version_rejected), document_id, document, version, change_type, reason, date
Document published event (document_published), document_id, document, author (author’s display name), date

The acknowledgement payload has no event field — a payload containing date_signed is an acknowledgement.

Email address: The user’s email address is not included in the acknowledgement payload by default, and there is no setting on the settings screen to add it. Sites that need it must have it enabled by a developer.


Security — HMAC signature

When a signing secret exists, every webhook request carries two headers:

  • X-DPMA-Timestamp — the Unix time the request was signed
  • X-DPMA-Signature — sha256= followed by an HMAC-SHA256 of the timestamp, a full stop, and the raw request body (<timestamp>.<body>), keyed with your signing secret

The signing secret is generated for you. It appears read-only in the Webhook Signing Secret field as soon as you have saved a webhook URL, so you can configure your receiver before the first delivery. You do not choose it — copy it from there into your receiving system. Treat it like a password.

Click Regenerate secret to rotate it. Rotation takes effect immediately, so any receiver still holding the old value will stop verifying deliveries until you update it there too.

Your receiving endpoint should verify the signature before processing the payload, and should reject any request whose timestamp is more than 5 minutes away from its own clock. This prevents malicious actors from spoofing or replaying events to your endpoint.

Verifying the signature (PHP example):

// Copy this from the Webhook Signing Secret field in your plugin settings.
$secret    = 'paste_the_generated_signing_secret_here';
$payload   = file_get_contents( 'php://input' );
$timestamp = $_SERVER['HTTP_X_DPMA_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_DPMA_SIGNATURE'] ?? '';

// Reject stale or future-dated requests (5-minute window).
if ( ! ctype_digit( $timestamp ) || abs( time() - (int) $timestamp ) > 300 ) {
    http_response_code( 401 );
    exit;
}

$expected = 'sha256=' . hash_hmac( 'sha256', $timestamp . '.' . $payload, $secret );

if ( ! hash_equals( $expected, $signature ) ) {
    http_response_code( 401 );
    exit;
}

Retry behaviour

Webhooks are sent in the background shortly after the event, so they never slow down the person acknowledging. Your endpoint should respond within 3 seconds.

If the receiving endpoint returns a 5xx error, times out, or can’t be reached, the plugin retries with increasing delays:

  • First retry: 1 minute after the failure
  • Second retry: 5 minutes after the first retry
  • Third retry: 30 minutes after the second retry

If the delivery still fails after these retries, it is recorded as failed and dropped. 4xx responses (for example 404 or 403) are not retried — these indicate a configuration problem that needs human attention.

Successful and failed deliveries are recorded in the plugin’s internal event log. There is no delivery log screen in the admin, so use your receiving system’s logs to confirm deliveries.


Setting up webhooks

  1. Go to Policy Management → Settings → Acknowledgements & Notifications.
  2. In the Acknowledgement Settings section, enter your endpoint in Acknowledgement Webhook URL. It must use HTTPS — a plain HTTP or invalid URL is rejected and the webhook is disabled.
  3. Under Webhook Events, untick any events you don’t want to send.
  4. Click Save Changes.
  5. Copy the Webhook Signing Secret that now appears into your receiving system.
  6. Trigger a real event (for example, acknowledge a test document) and confirm your endpoint receives it. There is no built-in “send test” button.

To turn webhooks off completely, clear the Acknowledgement Webhook URL field and save.

Settings at a glance:

Setting Default Allowed values
Acknowledgement Webhook URL Empty (webhooks off) One HTTPS URL
Webhook Events All four events on Any combination of Acknowledgement recorded, Version approved, Version rejected, Document published
Webhook Signing Secret Generated automatically when you first save a URL Read-only; rotate with Regenerate secret

Changes apply to deliveries already queued. The URL and event choices are checked again at the moment each delivery (or retry) is sent. If you clear the URL or switch an event off, deliveries still waiting to be sent are stopped too — they are not posted to the old address.

Webhooks stop while your Pro licence is not active.


Troubleshooting webhooks

Nothing arrives at my endpoint.

  • Check the URL starts with https://. A plain HTTP URL is rejected when you save.
  • Check the event you’re testing is ticked under Webhook Events.
  • Deliveries are sent by WordPress’s background task runner (WP-Cron), which runs when someone visits the site. On a site with WP-Cron disabled, set up a real cron job for wp-cron.php.
  • Make sure your Pro licence is active.

My endpoint rejects every request as unsigned or invalid.

  • Copy the Webhook Signing Secret again — it may have been regenerated.
  • Sign <timestamp>.<raw body> exactly as received. Re-encoding the JSON before hashing changes the bytes and breaks the signature.
  • Check your server clock. Requests more than 5 minutes from your clock fail the replay check in the example above.

Some deliveries arrive late. A failed delivery is retried after 1, 5 and 30 minutes, so one event can arrive up to about 36 minutes after the first attempt. Make your receiver tolerate duplicates and late arrivals, and use document_id plus date_signed (or date) to de-duplicate.

My endpoint gets a 4xx response and nothing retries. That’s by design — fix the endpoint or its authentication, then trigger a fresh event.


Privacy obligations

When you enable the webhook, you are sending personal data (user ID, display name and role, plus the approver’s or author’s name for the approval and publication events) to a third-party endpoint. You are responsible for:

  • Ensuring the receiving endpoint is secure and uses HTTPS
  • Documenting this data flow in your organisation’s privacy policy
  • Ensuring the receiving endpoint complies with any applicable privacy law (GDPR, Privacy Act, HIPAA, etc.)

The plugin adds text describing every webhook event and its payload to the WordPress Privacy Policy guide (Settings → Privacy → Policy Guide), which you can copy into your site privacy policy.


Common integration examples

Slack notification on acknowledgement: Slack’s incoming webhooks expect their own message format, so route the webhook through Zapier, Make or a small relay service that turns each acknowledgement into a Slack message in your chosen channel.

HR system update: Many HR systems (BambooHR, Employment Hero, Workday) accept webhooks to update employee records. Point the webhook at your HR system’s inbound webhook endpoint to automatically log policy sign-offs against employee profiles.

Audit management tool: Tools like Vanta, Drata, or Sprinto often have webhook ingest endpoints. Connect the plugin’s acknowledgement webhook to automatically populate your audit tool’s evidence library.

Zapier / Make (Integromat): Use a Zapier or Make webhook trigger to connect acknowledgement events to thousands of other applications without writing any code.


Worked example: logging policy sign-offs in an HR system

Marcus runs IT for a 60-person accounting firm. HR wants each acknowledgement of the Code of Conduct recorded against the employee in their HR system.

  1. He creates a small relay on the firm’s existing automation platform that accepts a POST, verifies the signature, and calls the HR system’s API. It gives him an HTTPS address.
  2. In Settings → Acknowledgements & Notifications, he pastes the address into Acknowledgement Webhook URL. HR only cares about sign-offs, so under Webhook Events he unticks Version approved, Version rejected and Document published, then clicks Save Changes.
  3. He copies the Webhook Signing Secret that now appears into the relay’s configuration.
  4. He acknowledges a test document with his own account. Within a minute or so the relay receives a payload with his user_id, name, role, policy (for example “Code of Conduct (v3.0)”) and date_signed, and the relay confirms the signature.
  5. Because the payload has no email address, the relay matches staff by user_id, using a lookup table HR keeps of WordPress user IDs against employee numbers.
  6. He adds a line to the firm’s staff privacy notice saying acknowledgement records are shared with the HR system.

Version History

Version 1.0.0 Major October 4, 2026
Author: DHDW