How it works
The full request lifecycle — from script tag load to a decision — and every layer in between.
This page walks through everything that happens between a visitor loading your page and your backend receiving a decision. Each stage links to its own deep-dive page for the full detail.
The three phases of a session
Not one check — three, layered on top of each other
KaizoCore doesn't make one decision at page load and stop. A session moves
through up to three distinct phases, each producing signal the final
/v1/decide call can use.
1. FORGE — the initial challenge (page load)
When the collector script loads, it runs FORGE: a hardware-bound challenge combining a proof-of-work puzzle, an ECDH key exchange, and an encrypted collection payload. This does three things at once:
- Proves the client can execute real, non-trivial JavaScript (a bare HTTP client can't solve the PoW).
- Establishes an encrypted channel for the behavioral payload, so a man-in-the-middle or naive proxy can't tamper with or replay it.
- Issues a cryptographically signed, short-lived cookie binding the session to the originating IP and User-Agent — the first defense against a token being lifted and reused from a different machine.
FORGE takes on the order of a few hundred milliseconds and runs once per session.
2. PULSE — the continuous heartbeat (whole session)
After FORGE completes, the SDK sends a lightweight heartbeat every 4 seconds for as long as the page is open: mouse movement statistics, scroll deltas, keystroke inter-arrival times. Each heartbeat is independently scored as clean or robotic. A robotic tick doesn't just pause the session's good standing — it actively resets accumulated trust, on the theory that a single bad tick is a real signal, not noise to average away.
This is the architectural answer to "what if a bot solves the initial challenge and then runs unattended?" — see PULSE for the full mechanics, including exactly what "robotic" means mathematically.
3. The ack token — server-attested checkout credential
At the moment of checkout (or any sensitive action you gate this way), your backend can request an ack token: a signed, single-use credential that KaizoCore only issues if the session has sustained multiple clean PULSE ticks in a row, has valid collect-time evidence, and stays under conservative ML-confidence thresholds. The token is bound to a purchase-context hash, has a 30-second TTL, and is consumed exactly once. See Ack tokens.
The decision request
Whether or not you use ack tokens, the core integration point is one call:
POST /v1/decideYour backend calls this with the visitor's IP, user agent, session token, and
whatever else you know (entity keys like a user ID or email, the event type
— login, checkout, signup, payment). KaizoCore responds with a
decision. See The /v1/decide API for the full schema.
What happens inside /v1/decide
Seven scoring layers, one fused score
Every rule belongs to exactly one of seven layers: network, device, environment, behavior, journey, entity, session. Each layer contributes its single highest-firing rule, weighted, to a 0–100 score. See The scoring engine for the full rule list and weights.
- Rate limiting and HMAC request signing are checked first — every
/v1/decidecall is signed the same way (sk_live_on your backend,pk_live_from the SDK), so a stolen API key alone isn't enough to forge decisions without also matching the signature. - IP enrichment — country, ASN, and connection type (residential, datacenter, VPN, Tor, CGNAT) via a real-time lookup.
- Bad-actor registry lookup — the request's device fingerprint is checked against KaizoCore's cross-customer bad-actor registry (correlation only — see Why KaizoCore for why this never adds trust, only risk) and against your own block/allow list.
- The invisible edge layer — a fast-path
BLOCKfor the highest- confidence cases (a known-bad TLS client fingerprint combined with a registry match), skipping the rest of scoring entirely for latency. - Velocity and impossible-travel checks — per-IP and per-entity request rate, plus a physical-plausibility check on consecutive requests from the same identity (see Impossible travel).
- The seven-layer rule engine runs, producing a raw 0–100 score and a list of fired reasons.
- ML fusion blends the rule-based score with two shadow ML models (a supervised classifier and an unsupervised anomaly detector), gated by how complete the available behavioral evidence is. See ML fusion.
- Policy overrides — if you've configured a policy engine override for a rule that fired, it's applied here (escalation only — never used to downgrade a decision the score already earned).
- The final decision — one of five bands, see Decision scores for exact thresholds.
- Async, non-blocking: the decision is logged, the entity graph is updated, and any matching webhooks are dispatched — none of this adds latency to your response.
Design principles that show up everywhere
These aren't abstract values — they're specific, checkable rules the codebase is built to follow:
- Fingerprints correlate, never grant trust. Covered above and in Why KaizoCore.
- Absence of a signal is never suspicious by itself (the "Golden Rule").
A touchscreen user with no mouse data, a first-ever request with no travel
history to compare against, a session with no completed
collect()call — none of these are penalized for the absence alone. Every rule that depends on optional evidence is gated on that evidence's presence. - Escalation-only overrides. Policy overrides, list entries, and the
late "GHOST" uncanny-valley override can all push a decision up toward
BLOCK— none of them can downgrade a decision the underlying score already earned on its own. - Everything real is disclosed, including the gaps. See FAQ for exactly what KaizoCore does and doesn't currently catch.