Skip to navigation

Finding webhooks

Detectant can send an HTTPS webhook when a direct API scan or enabled S3 integration finds a suspicious or malicious file. Configure the destination and select Webhook under Dashboard → Settings → Notification settings. You can use webhook delivery by itself or together with email.

Event

Every notification uses the finding.detected event type. The request body is JSON and the detected_at value is an ISO 8601 timestamp.

For a direct API scan:

{
"type": "finding.detected",
"source": {
"type": "api"
},
"finding": {
"scan_id": "scan_01JEXAMPLE",
"verdict": "malicious",
"detection": "Malicious content",
"reason": "The file matched one or more malicious indicators.",
"size_bytes": 24812,
"sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"detected_at": "2026-08-30T10:00:00.000Z"
},
"file": {
"filename": "invoice.pdf"
}
}

For an S3 integration, source identifies the integration and file identifies the exact object:

{
"type": "finding.detected",
"source": {
"type": "s3",
"integration_id": "162f1d7b-0f97-48af-b7ea-1fbc7a7c19e4",
"integration_name": "Customer uploads"
},
"finding": {
"scan_id": "scan_01JEXAMPLE",
"verdict": "suspicious",
"detection": "File type mismatch",
"reason": "The file content does not match its declared type.",
"size_bytes": 24812,
"sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"detected_at": "2026-08-30T10:00:00.000Z"
},
"file": {
"bucket": "customer-uploads",
"object_key": "incoming/invoice.pdf"
}
}

verdict is either suspicious or malicious. Treat fields you do not recognize as forwards-compatible additions.

Verify the signature

Detectant signs the exact raw request body using the signing secret shown in notification settings. The request includes these Standard Webhooks headers:

  • webhook-id: a stable identifier for this finding notification. Use it to deduplicate processing.
  • webhook-timestamp: the signing time as Unix seconds.
  • webhook-signature: one or more versioned signatures, currently v1,<base64-signature>.

To calculate the expected signature:

  1. Remove the whsec_ prefix from the signing secret and Base64-decode the remainder.
  2. Join the webhook ID, timestamp and unmodified raw body with periods: <id>.<timestamp>.<raw-body>.
  3. Calculate HMAC-SHA256 with the decoded secret and Base64-encode the result.
  4. Compare it with the v1 signature using a timing-safe comparison.

Reject requests with missing headers, an invalid signature, or a timestamp outside a short tolerance such as five minutes. Verify the signature before parsing JSON, and never log the signing secret or full request headers.

Delivery behavior

The endpoint must use HTTPS and a public hostname. Detectant waits up to five seconds and accepts any 2xx response as successful. Redirects and non-2xx responses are treated as failures. Failed deliveries are retried independently with capped exponential backoff; the saved finding remains available and the file is not scanned again. Because a request can succeed immediately before its response is lost, use webhook-id to safely ignore duplicate deliveries. Respond quickly after safely recording the event and perform slower work asynchronously.

Keep the signing secret private. If it is exposed, select Rotate signing secret in notification settings and update your receiver immediately. New delivery attempts use the rotated secret; a request already in flight when rotation completes may still carry the previous signature.