Webhook events
Each webhook subscribes to one or more event types. You can subscribe to any combination at creation time and change it later. Events fire from every scoring decision regardless of whether the call was via JS widget or server-side API.
| Event | Fires when | Volume |
|---|---|---|
check.created |
Every scored signup, regardless of verdict. | High — one per scoring call. |
check.blocked |
Verdict was block. |
Low — typically <5% of traffic. |
check.review |
Verdict was review. |
Low-medium — typically 5-15%. |
check.high_risk |
Score ≥ 75, regardless of verdict. | Low — useful for alerting separately from the verdict. |
verdict.overridden |
An operator changed a verdict (false-positive correction). | Very low — mostly retroactive corrections. |
Choosing events
Most customers want check.blocked and check.high_risk only.
They're cheap (low volume) and surface the actionable signal. Subscribe to
check.created only if you're piping everything into a data warehouse.
Multiple events from one check
A single scored signup can fire multiple events. A blocked, score-95 signup fires
check.created + check.blocked + check.high_risk —
three separate deliveries, each with their own signature, idempotency key, retry state.
Deduplicate on data.id on your end if you only want each check once.
Payload schema
Every event body follows this shape:
{
"event": "check.blocked",
"timestamp": 1748094182, // unix epoch seconds
"data": {
"id": "fef019b3-...", // check UUID
"score": 87, // 0-100
"verdict": "block", // allow|review|block
"reasons": [{"code":"IP_DATACENTRE","weight":35,...}],
"mode": "live", // live|test
"form_id": "uuid or null",
"signup": {
"email": "user@example.com",
"phone": "+447700900111",
"country": "GB",
"ip": "192.0.2.1"
// password is never included
},
"model_version": "v1.lightgbm.2026-05-16",
"duration_ms": 142
}
}