Webhooks
Configure real-time event notifications
Webhooks API
Receive real-time notifications when events occur in ModernPentest.
List Webhooks
GET /webhooksRetrieve all configured webhooks.
Response
{
"data": [
{
"id": "wh_abc123",
"url": "https://your-server.com/webhook",
"events": ["scan.completed", "vulnerability.found"],
"status": "active",
"created_at": "2025-01-01T00:00:00Z",
"last_triggered_at": "2025-01-15T10:30:00Z"
}
]
}Get Webhook
GET /webhooks/{id}Get details about a specific webhook.
Response
{
"id": "wh_abc123",
"url": "https://your-server.com/webhook",
"events": ["scan.completed", "vulnerability.found"],
"status": "active",
"secret": "wh_sec_••••••••",
"created_at": "2025-01-01T00:00:00Z",
"last_triggered_at": "2025-01-15T10:30:00Z",
"delivery_stats": {
"total_delivered": 150,
"total_failed": 2,
"success_rate": 98.7
}
}Create Webhook
POST /webhooksCreate a new webhook endpoint.
Request Body
{
"url": "https://your-server.com/webhook",
"events": ["scan.completed", "vulnerability.found"],
"secret": "your_webhook_secret",
"headers": {
"X-Custom-Header": "custom-value"
}
}Parameters
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | HTTPS endpoint URL |
events | array | Yes | Events to subscribe to |
secret | string | No | Secret for signature verification |
headers | object | No | Custom headers to include |
Available Events
| Event | Description |
|---|---|
scan.started | Scan has begun |
scan.progress | Scan progress update |
scan.completed | Scan finished successfully |
scan.failed | Scan encountered error |
vulnerability.found | New vulnerability discovered |
vulnerability.updated | Vulnerability status changed |
vulnerability.fixed | Vulnerability marked fixed |
report.ready | Report available for download |
Response
{
"id": "wh_new456",
"url": "https://your-server.com/webhook",
"events": ["scan.completed", "vulnerability.found"],
"status": "active",
"secret": "wh_sec_••••••••",
"created_at": "2025-01-15T12:00:00Z"
}Example
curl -X POST https://api.modernpentest.com/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhook",
"events": ["scan.completed", "vulnerability.found"],
"secret": "my-secret-key"
}'Update Webhook
PATCH /webhooks/{id}Update webhook configuration.
Request Body
{
"events": ["scan.completed"],
"status": "paused"
}Delete Webhook
DELETE /webhooks/{id}Remove a webhook endpoint.
Response
{
"deleted": true,
"id": "wh_abc123"
}Webhook Payload Format
All webhook deliveries follow this structure:
{
"id": "evt_xyz789",
"event": "vulnerability.found",
"timestamp": "2025-01-15T10:30:00Z",
"data": {
// Event-specific data
}
}Event Payloads
scan.completed
{
"id": "evt_001",
"event": "scan.completed",
"timestamp": "2025-01-15T10:45:00Z",
"data": {
"scan_id": "scan_xyz789",
"application_id": "app_abc123",
"application_name": "Production App",
"type": "standard",
"duration_seconds": 2700,
"findings_count": {
"critical": 0,
"high": 2,
"medium": 5
}
}
}vulnerability.found
{
"id": "evt_002",
"event": "vulnerability.found",
"timestamp": "2025-01-15T10:30:00Z",
"data": {
"vulnerability_id": "vuln_001",
"title": "SQL Injection",
"severity": "critical",
"application_id": "app_abc123",
"application_name": "Production App",
"scan_id": "scan_xyz789",
"location": {
"url": "/api/users",
"parameter": "id"
}
}
}Signature Verification
Verify webhook authenticity using the X-ModernPentest-Signature header.
Node.js Example
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
const expectedSig = `sha256=${expected}`;
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSig)
);
}
// Express middleware
app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
const signature = req.headers['x-modernpentest-signature'];
if (!verifyWebhook(req.body, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body);
// Process event...
res.status(200).send('OK');
});Python Example
import hmac
import hashlib
def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode('utf-8'),
payload,
hashlib.sha256
).hexdigest()
expected_sig = f"sha256={expected}"
return hmac.compare_digest(signature, expected_sig)Delivery & Retries
Delivery Expectations
- Webhooks are delivered within seconds of events
- Timeout: 30 seconds
- Expected response: 2xx status code
Retry Policy
Failed deliveries are retried with exponential backoff:
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | 1 minute |
| 3 | 5 minutes |
| 4 | 30 minutes |
| 5 | 2 hours |
After 5 failed attempts, the webhook is marked as failing.
Test Webhook
POST /webhooks/{id}/testSend a test event to verify your endpoint.
Response
{
"delivered": true,
"response_status": 200,
"response_time_ms": 150
}Webhook Logs
GET /webhooks/{id}/logsView recent delivery attempts.
Response
{
"data": [
{
"id": "log_abc123",
"event": "vulnerability.found",
"status": "delivered",
"response_status": 200,
"response_time_ms": 150,
"attempted_at": "2025-01-15T10:30:00Z"
},
{
"id": "log_xyz789",
"event": "scan.completed",
"status": "failed",
"response_status": 500,
"error": "Server returned 500 Internal Server Error",
"attempted_at": "2025-01-15T09:00:00Z",
"retry_at": "2025-01-15T09:05:00Z"
}
]
}Last updated: December 8, 2025