Webhook payloads¶
Reference for the JSON bodies posted to your configured outbound webhook. For setup and signature verification see the Outbound webhook guide.
Common envelope¶
Every event uses the same outer shape:
{
"event": "<event_type>",
"delivered_at": "<ISO-8601 UTC>",
"client_slug": "<your account slug>",
"finding": { ... }
}
event— one of the event types below.delivered_at— when CredWatch sent the request, not when the underlying state change happened. The finding itself contains its own timestamps.client_slug— useful if your endpoint receives webhooks from multiple CredWatch accounts (rare but possible for MSPs).finding— full finding object, identical shape to what the GET /api/v1/findings/{id} returns.
Event types¶
finding.validated¶
Fires when the validation worker has tested a freshly-detected finding against the issuing service and confirmed it's a real credential.
{
"event": "finding.validated",
"delivered_at": "2026-05-21T14:33:12Z",
"client_slug": "acme",
"finding": {
"id": "01HXYZ...",
"status": "active",
"validation_status": "valid",
"validation_confidence": "high",
"composite_score": 87,
"source_type": "repo",
"source_visibility": "public",
"source_url": "https://github.com/acme/web/blob/abc/src/config.ts#L42",
"repo_full_name": "acme/web",
"file_path": "src/config.ts",
"line_number": 42,
"matched_text": "sk-a1****cd34",
"pattern": {
"name": "OpenAI API Key",
"secret_type": "openai"
},
"first_seen_at": "2026-05-21T14:30:01Z",
"last_seen_at": "2026-05-21T14:30:01Z",
"seen_count": 1
}
}
This is the primary signal — fires for every validated finding regardless of score. If you only want to act on high-severity ones, filter on composite_score in your handler.
Use this to: import into a SIEM, notify a custom Slack channel, file a ticket in a tracker we don't natively support, kick off an automated rotation workflow.
finding.resolved¶
Fires when a finding transitions to resolved — either manually in the portal/API, or auto-resolved on rescan when CredWatch confirms the credential is gone.
{
"event": "finding.resolved",
"delivered_at": "2026-05-21T16:02:08Z",
"client_slug": "acme",
"finding": {
"id": "01HXYZ...",
"status": "resolved",
"resolved_at": "2026-05-21T16:02:05Z",
"resolution_note": "Rotated key, force-pushed to remove commit",
"resolution_evidence": {
"auto_resolved": false,
"resolved_by": "[email protected]"
},
"validation_status": "invalid",
"composite_score": 87,
"source_url": "https://github.com/acme/web/blob/abc/src/config.ts#L42",
"matched_text": "sk-a1****cd34",
"pattern": {
"name": "OpenAI API Key",
"secret_type": "openai"
}
}
}
Use this to: close the corresponding incident in your tracker, update internal compliance dashboards, post a "resolved" message into Slack.
finding.false_positive¶
Fires when a finding is marked as a false positive in the portal or via the API.
{
"event": "finding.false_positive",
"delivered_at": "2026-05-21T15:44:00Z",
"client_slug": "acme",
"finding": {
"id": "01HXYZ...",
"status": "false_positive",
"source_url": "...",
"pattern": {"name": "Generic API Key", "secret_type": "generic"}
}
}
Use this to: prune your local copy of CredWatch data, train internal models on which matches are noise.
Headers¶
POST /your-endpoint HTTP/1.1
Content-Type: application/json
X-CredWatch-Signature: sha256=8f4a3b2c...
User-Agent: CredWatch-Webhook/1.0
| Header | Use |
|---|---|
X-CredWatch-Signature |
HMAC-SHA256 of the raw body with your webhook secret. Verify. |
User-Agent |
Always CredWatch-Webhook/1.0. Optional to check. |
Content-Type |
Always application/json. |
Delivery semantics¶
- At most once — we do not retry on failure.
- Timeout — 10 seconds. Slower endpoints will time out and the event is dropped.
- Ordering — not guaranteed. A
resolvedevent for one finding may arrive before thevalidatedevent for another.
For critical workflows, backstop the webhook with a periodic GET /api/v1/findings pull.
Securing your endpoint¶
Beyond signature verification, defence-in-depth:
- IP allowlist the CredWatch egress IP (we publish it; contact support if you need it).
- Reject events with
delivered_atolder than 5 minutes to prevent replay attacks. - Log all received events with their signature and verification result for audit.