Skip to content

Behavioral Signals

A wd_clearance token normally says one thing: this is a real browser that hasn’t tripped deception. Behavioral signals let a session say something stronger — a human is driving this — which upgrades the token to the human-likely trust level your most sensitive routes can require.

To do that we need evidence of how the session moves. This page is the complete, exhaustive statement of what that means. It exists because “we analyze user behavior” is exactly the sentence that should make you ask what, precisely, is leaving your visitors’ browsers.

Four kinds of number, and nothing else:

KindFields
Countspointer samples, scroll events, keystrokes, touch points
Durationslength of the observation window, how long a click was held
Variancespointer velocity, inter-event timing, touch force
Ratiosmicro-tremor and path collinearity, each 0–1

That is the entire payload. In the SDK it is the BehaviorAggregate type, and summarizeBehavior() is the only function that builds it — a test asserts the exact field list, so it cannot grow without a deliberate change to this page.

A representative payload:

{
"samples": 180, "duration_ms": 4200,
"tremor": 0.11, "straight_ratio": 0.34,
"velocity_var": 0.42, "delta_var": 61.5,
"dir_changes": 27, "micro_moves": 19, "hold_ms": 84,
"touch_points": 0, "touch_force_var": 0, "pointer_nonmouse": false,
"scrolls": 6, "keys": 12
}
  • No pointer coordinates. We record that the pointer changed direction 27 times, never where it went.
  • No keystroke content. keys: 12 means twelve keys were pressed. Which keys is never recorded, never transmitted, and never stored — not even in hashed form.
  • No form values, no field names, no clipboard.
  • No page or element content, no DOM, no text, no URLs.
  • No session replay. There is no event stream, no timeline, and no recording. Nothing collected here can be played back, because aggregates are not reversible into the events that produced them.

The distinction in one line: these signals describe how a session moved, never what it did.

That is the whole difference between this and a session-replay product. Replay vendors capture the DOM and an ordered event stream so a human can watch the session later; that is a fundamentally different data set with fundamentally different risk, and it is not what runs here. Every number above could be published next to a session without revealing anything about the person in it.

  1. The browser SDK observes the session and, once there has been enough interaction, posts the aggregates with a token mint.
  2. The server decides what they earn. The browser reports observations and never a verdict — a client that sends flattering numbers gains nothing it could not gain by lying about its fingerprint.
  3. The server produces a human_likelihood score of 0–100. Above a threshold, the mint attaches a behavioral evidence tag and grades the token human-likely.
  4. The score is recorded against the actor as a running average, shown in the actor view alongside — never folded into — the threat score. An actor that scores high on both (real hands driving an automation tool) is a case a single blended number would hide.

The trust grade is capped by the actor’s threat score: positive behavioral evidence cannot lift a token whose actor is already known to be bot-like.

It only grades up. A session with no behavioral evidence mints exactly the clean token it always did. There is no path from these signals to a block, a challenge, or a refusal.

That matters most for the sessions that have nothing to report:

  • Keyboard-only and assistive-technology users produce no pointer cadence. They are unscored, not scored badly — the code distinguishes “too little interaction to judge” from “judged and looked machine-like”, and only the second is a low score. Behavioral data must never become an accessibility barrier, so a route requiring human-likely should be a deliberate choice for a narrow set of paths, not a site-wide default.
  • Very short sessions are unscored for the same reason.
  • Automation with human-emulation on (tools that synthesize plausible mouse curves) can score well. This is one input among many, not a verdict, which is why the threat cap exists and why deception remains the primary detection mechanism.

Turning it off is one flag — clearance still works, and tokens simply stay at the clean grade:

startClearance({ siteKey: 'YOUR_SITE_KEY', behavior: false });

Listeners are passive, so they never delay scrolling or input. Collection stops as soon as the summary is delivered — a cleared session has no steady-state cost. The device fingerprint (one canvas and one WebGL read, the only expensive step) is computed only when an upgrade is actually about to happen, so a session that never interacts never pays for it. At most one upgrade mint occurs per page load, and a session that never interacts sends nothing at all.

  • Clearance Enforcement — how tokens are verified at the edge, and how to require a minimum trust level per route
  • Actors — the identity the score is recorded against