Skip to main content
When a session crosses your configured risk threshold, InsightAI delivers a risk.alert event to your webhook URL (or over the live socket channel, for dashboard integrations). This page documents every field in that payload.
Not every field is populated on every alert — entity.device.fingerprint_js only applies to web sessions, correlation only appears when a device/visitor has meaningful cross-account history, and so on. Treat absent fields as “not applicable to this session,” not as an error.

Full example payload

If you copied this payload from an earlier version of this doc: the stream object needs a trailing comma before "data" — a bare object followed directly by another key without a comma is invalid JSON. The example above is corrected.

Envelope fields

integer
Payload schema version. Check this before parsing if you maintain multiple integration versions — a version bump signals a field addition or shape change.
string
Always risk.alert for this event. Reserved for future event types (e.g. case.updated from the AML side).
string
RISK_ONLY for Device Intelligence alerts. Distinguishes this stream from AML case-investigation events on shared infrastructure.
string
ISO-8601 timestamp of when this event was generated — not necessarily when the underlying session activity occurred.
integer
Monotonically increasing sequence number per tenant stream. Use this to detect gaps (missed deliveries) or out-of-order delivery, not ts — clock skew makes ts unreliable for ordering.
object

data.decision

string
PASS / REVIEW / BLOCK — the recommended action. Same three-tier model as RASP’s on-device scoring (see RASP — Scoring & decisions), but computed server-side with the full graph and analytics context RASP alone doesn’t have.
string
LOW / MEDIUM / HIGH / CRITICAL — independent of action; a REVIEW can still carry HIGH severity if you want severity-based routing separate from the action itself.
number
0–1. Note this is a different scale from RASP’s 0–100 rasp_score — don’t conflate the two when building unified dashboards.
number
0–1. How confident the model is in this decision, independent of how risky it is — a high-risk, low-confidence alert is a good candidate for REVIEW rather than an automatic BLOCK.

data.entity.device

The device fingerprint block. fingerprint_js only appears for web sessions (see Beyond RASP — web fingerprinting); native app sessions carry the SDK’s own device_id and RASP signal set instead, delivered on the telemetry ingest payload rather than here.

data.analytics

The three sub-objects here are the “beyond RASP” signals described conceptually in Beyond RASP:
object
Events-per-minute against a rolling threshold, with burst_detected flagging sudden spikes rather than sustained high volume.
object
How many times this device/visitor/IP has appeared across distinct accounts within the stated window. High reuse counts are the core multi-accounting signal.
object
automation_likelihood is the single composite score most integrations key off directly — it’s already a combination of mouse_entropy and timing_variance, so you rarely need the two sub-components separately unless you’re building your own weighting.

data.correlation

Only populated when there’s meaningful cross-account history — this is the device-to-user graph described in Beyond RASP, rendered as a snapshot at alert time.
array
Each entry is one device and the full list of user IDs it’s been seen on. A list longer than 1–2 unrelated users is the core multi-accounting signal.
array
Same idea for the browser-fingerprint visitor_id, for web sessions.
object
Count of distinct sessions from the same IP within the stated window — useful for detecting a single physical location (or NAT/proxy exit point) driving many sessions, distinct from device- or visitor-level reuse.

data.flags and data.reasons

Two related but distinct fields — don’t build logic against flags alone:
string[]
A flat list of everything that fired — good for tagging/filtering in your own systems (e.g. “show me all VPN_SUSPECTED alerts this week”), but carries no weight information.
array
The same signals, but with a weight (contribution to the overall risk score) and evidence (the actual numbers behind the flag). This is what you want for anything that explains why a decision was made — an analyst-facing UI, an audit trail, or a dispute-resolution flow.
A common integration mistake: building a rules engine against flags (string matching) instead of reasons (structured, weighted). flags is for filtering; reasons is for reasoning about the decision.

data.client_action_hint

Suggested step-up controls — e.g. 3DS, OTP, KYC_STEP_UP. Advisory, not enforced by InsightAI — your integration decides whether and how to apply them.
integer
How long this recommendation should be considered valid. Don’t apply a stale hint to a much-later action on the same session.
string
A human-readable summary, suitable for direct display in an analyst console without further formatting.

data.additional_data

Pass-through fields you supplied at ingest time (e.g. order_id, payment_attempt_id) — echoed back unchanged so you can correlate the alert with your own transaction record without a separate lookup.

Delivery and retries

Webhook delivery uses exponential backoff on non-2xx responses, up to a bounded number of attempts before an event is marked failed. Always verify the signature (see Authentication) and return a 2xx quickly — do heavier processing asynchronously rather than inside the webhook handler itself, since a slow handler risks the delivery being retried unnecessarily.