Skip to main content
Every SpoofSense check returns a genuine_score in [0, 1] — higher means more likely a genuine, live capture — and applies one rule to produce a binary decision:
Understanding how that score is calibrated and how the threshold is chosen gives you the control you need to tune the system for your risk tolerance.

The score is calibrated

Raw model probabilities shift when models are retrained. SpoofSense remaps every model’s output so that the decision boundary always sits at 0.5: a threshold you tune today keeps meaning the same thing after a model update, and thresholds are comparable across products. Model internals — architecture, raw per-class probabilities — are deliberately not exposed.

Where the threshold comes from

The threshold is resolved in priority order — the first match wins:
  1. Per-request overridethreshold (or thresholds on unified) in the request body.
  2. Organization default — set per product in the console (Dashboard → Settings).
  3. Platform default0.5.
The threshold actually applied is echoed back in every response, so your logs always show exactly which rule made the call.

Tuning guidance

Start at the default 0.5 and only move after measuring on your own traffic. Small adjustments — 0.05 at a time — make it easier to attribute changes in accept/reject rates.

Unified detection and per-product thresholds

On POST /v1/unified_detection, the overall decision is "real" only if every product’s check passes its own threshold. The per-product outcomes are in checks:

Thresholds in verification sessions

For verification sessions, thresholds are fixed server-side at session creation — the client can never loosen them. Set the threshold when calling POST /v1/verification_sessions from your backend; it will be honored when the session is scored.