Webhook Payload Reference

This reference documents the webhook payload structure sent by Content Guard Pro when security findings are detected.

Webhook Overview #

  • Method: POST
  • Content-Type: application/json
  • Timeout: 30 seconds
  • Retry Policy: Exponential backoff, 5 attempts

Headers #

Header Description
——– ————-
Content-Type Always application/json
X-CGP-Event Event type (e.g., critical_finding)
X-CGP-Site Source site URL
X-CGP-Signature HMAC-SHA256 signature (if secret configured)
User-Agent Content-Guard-Pro/1.0

Signature Verification #

If a webhook secret is configured, verify authenticity:

X-CGP-Signature: sha256=5d8e5a9f3b2c1d4e...

The signature is computed as:

HMAC-SHA256(payload_body, webhook_secret)

PHP Verification Example #

$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_CGP_SIGNATURE'] ?? '';

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

if (!hash_equals($expected, $signature)) { http_response_code(401); die('Invalid signature'); }

$data = json_decode($payload, true); // Process webhook...

Event Types #

critical_finding #

Sent when a Critical severity finding is detected.

finding_detected #

Sent for any finding (when severity threshold includes lower severities).

test #

Sent when “Send Test Webhook” is clicked.

Payload Structure #

Full Payload Example #

{
    "site": {
        "url": "https://yoursite.com",
        "name": "Your Site Name",
        "blog_id": 1,
        "wordpress_version": "6.4.2",
        "plugin_version": "1.0.0"
    },
    "event": "critical_finding",
    "finding": {
        "id": 12345,
        "fingerprint": "a1b2c3d4e5f6...",
        "severity": "critical",
        "confidence": 92,
        "rule_id": "ext_script_non_allowlist",
        "category": "external_resources",
        "object": {
            "type": "post",
            "id": 678,
            "field": "post_content",
            "title": "My Blog Post",
            "url": "https://yoursite.com/my-blog-post/",
            "edit_url": "https://yoursite.com/wp-admin/post.php?post=678&action=edit"
        },
        "summary": "External script from suspicious-domain.example",
        "matched_excerpt": "[script tag pointing to suspicious-domain.example]",
        "domain": "suspicious-domain.example",
        "url": "https://suspicious-domain.example/file.js",
        "first_seen": "2025-01-15T10:30:00Z",
        "last_seen": "2025-01-15T10:30:00Z",
        "reputation": {
            "google_safe_browsing": {
                "threat_type": "MALWARE",
                "checked_at": "2025-01-15T10:30:05Z"
            },
            "phishtank": {
                "in_database": false
            }
        }
    },
    "actions": {
        "review_url": "https://yoursite.com/wp-admin/admin.php?page=content-guard-pro-findings&finding=12345",
        "quarantine_url": "https://yoursite.com/wp-admin/admin.php?page=content-guard-pro-findings&action=quarantine&finding=12345&_wpnonce=abc123"
    },
    "scan": {
        "scan_id": 789,
        "mode": "standard",
        "type": "scheduled"
    },
    "timestamp": "2025-01-15T10:30:10Z"
}

Field Reference #

site Object #

Field Type Description
——- —— ————-
url string Site URL
name string Site title
blog_id integer Blog ID (for multisite)
wordpress_version string WordPress version
plugin_version string Content Guard Pro version

finding Object #

Field Type Description
——- —— ————-
id integer Finding database ID
fingerprint string Unique finding identifier
severity string critical, suspicious, or review
confidence integer 0-100 confidence score
rule_id string Detection rule identifier
category string Finding category
summary string Human-readable description
matched_excerpt string Sanitized matched content
domain string Extracted domain (if applicable)
url string Full URL (if applicable)
first_seen string ISO 8601 first detection time
last_seen string ISO 8601 last detection time

finding.object Object #

Field Type Description
——- —— ————-
type string post, postmeta, or option
id integer Object ID
field string Field name
title string Post title (for posts)
url string Permalink (for posts)
edit_url string Admin edit URL

finding.reputation Object #

Contains results from reputation services (when available):

{
    "google_safe_browsing": {
        "threat_type": "MALWARE",
        "platform_type": "ANY_PLATFORM",
        "checked_at": "2025-01-15T10:30:05Z"
    },
    "phishtank": {
        "in_database": true,
        "verified": true,
        "phish_id": 123456,
        "checked_at": "2025-01-15T10:30:05Z"
    }
}

actions Object #

Field Type Description
——- —— ————-
review_url string Direct link to review finding
quarantine_url string One-click quarantine URL (includes nonce)

scan Object #

Field Type Description
——- —— ————-
scan_id integer Scan database ID
mode string quick or standard
type string manual, scheduled, or on_save

Test Payload #

When “Send Test Webhook” is clicked:

{
    "site": {
        "url": "https://yoursite.com",
        "name": "Your Site Name",
        "blog_id": 1
    },
    "event": "test",
    "message": "This is a test webhook from Content Guard Pro",
    "timestamp": "2025-01-15T10:30:00Z"
}

Severity Values #

Value Meaning
——- ———
critical Immediate action required
suspicious Investigation needed
review Worth checking

Category Values #

Value Description
——- ————-
external_resources Scripts, iframes, embeds
suspicious_urls Shorteners, tracking
hidden_content CSS-hidden elements
obfuscation Encoded/disguised code
seo_spam Keyword spam
javascript_injection XSS, event handlers
code_injection PHP patterns
cryptojacking Mining scripts
redirects Unauthorized redirects
link_analysis Anomalous patterns

Responding to Webhooks #

Your endpoint should:

1. Respond quickly (within 30 seconds)
2. Return 2xx status for successful receipt
3. Process asynchronously if needed

Success Response #

HTTP/1.1 200 OK

{"received": true}

Async Processing Pattern #

// Respond immediately
http_response_code(200);
echo json_encode(['received' => true]);

// Flush output if (function_exists('fastcgi_finish_request')) { fastcgi_finish_request(); }

// Process webhook $data = json_decode(file_get_contents('php://input'), true); // ... your processing logic

Retry Behavior #

If your endpoint fails:

Attempt Delay
——— ——-
1 Immediate
2 1 minute
3 5 minutes
4 15 minutes
5 1 hour

After 5 failures, webhook is abandoned (logged in webhook history).

What are your feelings
Updated on December 4, 2025
Scroll to Top