Webhooks
CodeDig can push events to your own endpoints as findings and analysis jobs are completed. Use webhooks to route notifications to Slack, your incident management tool, or a SIEM.
Overview
CodeDig's outgoing webhooks let you react to events in real time without polling the API. Common use cases:
- Post a Slack message when a critical security finding is detected
- Open a Jira ticket on high-severity findings
- Archive all findings to a SIEM for compliance audit trails
- Trigger a downstream CI step after analysis completes
Configuration
Navigate to Settings → Webhooks and click New webhook. Provide:
- Webhook URL — the HTTPS endpoint CodeDig should POST to
- Secret — used to sign each delivery (see Signature Verification)
- Events — choose which event types to subscribe to (see below)
- Repository scope (optional) — limit deliveries to a specific repo
You can also manage subscriptions via the API at POST /api/webhooks/subscriptions. See API Reference for the full schema.
Event Types
Subscribe to any combination of the following events:
| Event type | When fired |
|---|---|
| security.finding.created | A new security finding is detected in a PR or scan |
| security.finding.resolved | A previously reported finding is resolved (e.g. fixed in a follow-up PR) |
| security.scan.completed | A full security scan completes (all findings available) |
| analysis.completed | A PR gate analysis run finishes (pass or fail) |
| indexing.started | Repository indexing begins (after install or manual trigger) |
| indexing.completed | Repository indexing finishes successfully |
| indexing.failed | Repository indexing encountered an unrecoverable error |
| orchestration.workflow.completed | An orchestration workflow (multi-step analysis) completes |
| orchestration.workflow.failed | An orchestration workflow fails |
Payload Structure
CodeDig sends an HTTP POST with Content-Type: application/json. The body always includes a top-level envelope, with event-specific data in the data field. Example for security.finding.created:
{
"event_id": "evt_01HXYZ1234567890",
"event_type": "security.finding.created",
"tenant_id": "my-org",
"repo_id": "my-org/my-repo",
"timestamp": "2026-05-16T10:23:45Z",
"data": {
"finding_id": "f_abc123",
"severity": "high",
"category": "security",
"title": "SQL injection vulnerability",
"file": "src/db/query.ts",
"line": 42,
"pr_number": 99,
"run_id": "run_xyz"
}
}Signature Verification
Every delivery includes an x-webhook-signature header. The value has the format sha256=<hex-digest>, where the digest is computed as HMAC-SHA256 of the raw request body using your webhook secret as the key.
Always verify the signature before processing the payload, and read the raw body bytes — parsing JSON first can cause subtle byte-order differences.
const crypto = require('crypto');
/**
* Verify a CodeDig webhook request.
* @param {string|Buffer} body - Raw request body (do NOT parse JSON first)
* @param {string} signature - Value of the x-webhook-signature header
* @param {string} secret - Your webhook secret (set when creating the subscription)
* @returns {boolean}
*/
function verifyWebhookSignature(body, signature, secret) {
// Signature header format: "sha256=<hex-digest>"
const expectedHex = crypto
.createHmac('sha256', secret)
.update(typeof body === 'string' ? body : body.toString('utf8'))
.digest('hex');
const expected = Buffer.from(`sha256=${expectedHex}`, 'utf8');
const received = Buffer.from(signature, 'utf8');
if (expected.length !== received.length) return false;
return crypto.timingSafeEqual(expected, received);
}
// Express example
app.post('/codedig-webhook', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['x-webhook-signature'];
if (!sig || !verifyWebhookSignature(req.body, sig, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body);
console.log('Received event:', event.event_type);
res.sendStatus(200);
});Retry Policy
If your endpoint does not return a 2xx status code within the request timeout (default 30 seconds), CodeDig retries the delivery with exponential backoff. The retry schedule is:
- Attempt 1 — immediate
- Attempt 2 — ~30 s delay
- Attempt 3 — ~2 min delay
- Attempt 4 — ~8 min delay
- Attempt 5 — ~30 min delay (final attempt)
After 5 failed attempts, the delivery is marked as permanently failed. You can inspect and manually retry deliveries from the Delivery Log.
Delivery Log
Navigate to Settings → Webhooks → Deliveries to see the full history of every delivery attempt, including HTTP status, response body, and timing. You can replay any delivery from this view, which is useful during initial setup and debugging.
Related: API Reference · API Keys