Docs
← Home Sign In Get Started

Overview

Webhooks let Shieldome push scan results to any URL the moment a scan completes. Use them to send alerts to Slack, create tickets in Jira, or trigger downstream workflows in your own systems.

Shieldome sends an HTTP POST request with a JSON payload to your configured URL. If delivery fails, it retries automatically with exponential backoff (attempts at 0 s, 2 s, 4 s, 8 s). If all four attempts fail, the delivery is abandoned and the failure is recorded in the email log — no further retries occur.

Configuring a webhook

Option A — Per-scan webhook (one URL per scan run)

On the scan form, expand Advanced options and paste your webhook URL into the Webhook URL field before starting the scan. The notification fires once when that scan completes.

Option B — Global Slack / Discord webhook

  1. In the Shieldome app, go to SettingsIntegrations
  2. Scroll to the Slack or Discord section
  3. Enter your incoming webhook URL
  4. Click Save Webhook Settings

The global webhook fires for every scan that meets the configured severity threshold.

Option C — Per-scan webhook via API

Set a webhook URL directly in the scan request body:

json
{
  "target_url":      "https://your-app.com",
  "scan_type":       "vuln",
  "scan_authorized": true,
  "webhook_url":     "https://hooks.example.com/shieldome"
}

Payload format

Shieldome sends a JSON object with the following structure:

json
{
  "event":       "scan.completed",
  "scan_id":     "a1b2c3d4-...",
  "target_url":  "https://example.com",
  "status":      "completed",
  "started_at":  "2025-06-14T10:00:00Z",
  "completed_at":"2025-06-14T10:07:42Z",
  "summary": {
    "total":    12,
    "critical": 1,
    "high":     3,
    "medium":   5,
    "low":      2,
    "info":     1
  },
  "top_findings": [        // up to 3 highest-severity findings
    {
      "name":      "SQL Injection Indicator",
      "severity":  "critical",
      "owasp_id": "A03:2021"
    }
  ],
  "report_url":  "https://your-shieldome-url/app"
}

Retry behaviour

If your endpoint returns an HTTP 5xx error or is unreachable, Shieldome retries the delivery:

AttemptDelay after previous
1st (initial)Immediately
2nd2 seconds
3rd4 seconds
4th8 seconds

4xx errors (e.g. 404, 401) are not retried — they indicate a misconfiguration that won't resolve by itself.

After all 4 attempts are exhausted with no successful delivery, the webhook attempt is permanently abandoned. Check your endpoint logs if you suspect missed deliveries — Shieldome will not queue or replay them.

Receiving webhooks — example server (Python)

python
# webhook_receiver.py — minimal Flask receiver
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/shieldome', methods=['POST'])
def receive():
    data = request.get_json()
    scan_id  = data.get('scan_id')
    summary  = data.get('summary', {})
    critical = summary.get('critical', 0)

    print(f'Scan {scan_id}: {critical} critical finding(s)')

    if critical > 0:
        # send Slack alert, create Jira ticket, etc.
        alert_team(data)

    return jsonify({'ok': True}), 200

def alert_team(data):
    print(f'ALERT: critical findings on {data["target_url"]}')

if __name__ == '__main__':
    app.run(port=8080)

Receiving webhooks — example (Node.js)

javascript
// webhook-receiver.js
const express = require('express');
const app = express();
app.use(express.json());

app.post('/shieldome', (req, res) => {
  const { scan_id, summary, target_url } = req.body;
  console.log(`Scan ${scan_id} on ${target_url}:`, summary);

  if (summary.critical > 0) {
    // notify Slack, PagerDuty, etc.
    console.warn(`CRITICAL: ${summary.critical} issue(s) on ${target_url}`);
  }

  res.json({ ok: true });
});

app.listen(8080, () => console.log('Webhook receiver on :8080'));

Sending to Slack

The easiest way to get Shieldome alerts in Slack is to use a Slack Incoming Webhook URL directly as your Shieldome webhook URL. However, Slack expects a specific payload format, so you'll need a small relay server or use Zapier/Make as a middleware.

Alternatively, set your Shieldome webhook to point at a small relay that reformats the payload:

python
import requests
from flask import Flask, request, jsonify

app   = Flask(__name__)
SLACK = 'https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK'

@app.route('/relay', methods=['POST'])
def relay():
    d = request.get_json()
    s = d.get('summary', {})
    emoji = '🔴' if s.get('critical') else '🟠' if s.get('high') else '🟡'
    requests.post(SLACK, json={'text':
        f"{emoji} *Shieldome scan completed* — {d['target_url']}\n"
        f"Critical: {s.get('critical',0)} | High: {s.get('high',0)} | "
        f"Medium: {s.get('medium',0)}\n"
        f"<{d.get('report_url')}|View full report>"
    })
    return jsonify({'ok': True})

if __name__ == '__main__':
    app.run(port=8080)

Testing your webhook locally

Use ngrok to expose a local server to the internet for testing:

bash
# 1. Start your receiver
python webhook_receiver.py

# 2. In another terminal, expose it via ngrok
ngrok http 8080

# 3. Copy the https://xxxxx.ngrok.io URL
# 4. Paste it as your webhook URL in Shieldome
# 5. Run a scan — your local server receives the payload