Skip to main content
[ DOCS · WEBHOOKS ]

Webhooks

EVENT-DRIVEN CALLBACKS · HMAC-SHA256 SIGNED · RETRY ON FAILURE

Setting Up a Webhook

Navigate to Dashboard → Webhooks and add a URL that can receive POST requests. ShieldPi will send events to that URL as JSON payloads.

You can also create webhooks via the API:

POST /api/webhooks
X-API-Key: shpi_live_...
Content-Type: application/json

{
  "url": "https://your-server.com/shieldpi-webhook",
  "event_types": ["scan.completed", "scan.failed"]
}

Separately, per-target alert webhooks for the Live Agent Monitor are configured at POST /api/agent-monitor/target/{id}/webhook — see the Live Agent Monitor docs.

Event Types

EventTrigger
scan.startedScan begins processing
scan.completedScan finishes successfully
scan.failedScan encounters a fatal error
scan.completed_partialScan finishes with incomplete results (e.g. agent disconnected)
vulnerability.criticalA critical-severity finding is discovered during a scan

Payload Format

All webhook payloads follow the same envelope structure:

{
  "event": "scan.completed",
  "timestamp": "2026-04-16T14:30:00Z",
  "data": {
    "scan_id": "uuid",
    "target_id": "uuid",
    "target_name": "My Chatbot",
    "status": "completed",
    "security_score": 85,
    "security_grade": "B+",
    "total_findings": 7,
    "critical": 0,
    "high": 3,
    "medium": 2,
    "low": 2,
    "report_url": "https://api.shieldpi.io/api/scans/{id}/report"
  }
}

Verification

Each webhook request includes an X-ShieldPi-Signature header containing an HMAC-SHA256 signature of the request body using your webhook secret. Verify the signature before processing:

import hmac, hashlib

def verify_signature(body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)

Retry Policy

If your endpoint returns a non-2xx status code or times out (30s), ShieldPi retries the delivery up to 3 times with exponential backoff (1 min, 5 min, 30 min). After 3 failures, the event is dropped and logged.