Webhooks
Receive real-time notifications when scans finish, fail, or your usage changes. CodeSec sends a signed POST to each configured endpoint.
2 endpoints
https://api.acme.dev/hooks/codesecscan.completedscan.failedAdded 5/20/2026Last delivery just nowhttps://hooks.slack.com/services/T000/B000/XXXXusage.limit_reachedAdded 4/11/2026Last delivery 2d ago
Events
Each event delivers a JSON payload with a top-level event name and a data object.
scan.completedFired when a scan finishes successfully and results are ready.
{
"event": "scan.completed",
"created_at": "2026-06-03T10:04:12Z",
"data": {
"scan_id": "scan_123",
"target": "https://example.com",
"status": "completed",
"score": 87,
"findings_count": 4
}
}scan.failedFired when a scan could not complete (unreachable target, timeout).
{
"event": "scan.failed",
"created_at": "2026-06-03T10:04:12Z",
"data": {
"scan_id": "scan_124",
"target": "https://unreachable.example",
"status": "failed",
"error": "target_unreachable"
}
}subscription.updatedFired when the account's plan or subscription status changes.
{
"event": "subscription.updated",
"created_at": "2026-06-03T10:04:12Z",
"data": {
"plan": "business",
"previous_plan": "pro",
"status": "active"
}
}usage.limit_reachedFired when a plan quota (scans or requests) is exhausted.
{
"event": "usage.limit_reached",
"created_at": "2026-06-03T10:04:12Z",
"data": {
"resource": "scans",
"limit": 500,
"used": 500,
"period_end": "2026-07-01T00:00:00Z"
}
}Verifying signatures
Every request includes a CodeSec-Signature header — an HMAC-SHA256 of the raw request body using your endpoint’s signing secret. Always verify it before trusting a payload.
import crypto from class="tok-str">"crypto";
export function verifySignature(rawBody, signature, secret) {
const expected = crypto
.createHmac(class="tok-str">"sha256", secret)
.update(rawBody)
.digest(class="tok-str">"hex");
// Constant-time comparison
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}