Skip to content

Human Scoring

Read whether the current session comes from a real person at the moment your app makes a decision. The SDK keeps the score up to date as the user interacts, so reading it is instant: it does not wait for the network.

In this use case

Page What it covers
Human Scoring (this page) Read the classification at a decision point
User Consent Ask the user for permission before anything is recorded
Sensitive Screens Pause capture while a password or payment field is on screen
Custom Events Mark moments in your app on the session timeline
Sessions Start a new session on logout or account switch

When to use it

  • Before creating an account, submitting a form, or redeeming a promotion
  • Before a step that bots abuse: posting, voting, adding to cart, claiming a reward
  • To decide which branch of your own flow to take — let the user through, or add a challenge

Prerequisites

  • The SDK is installed and initialized. See the Quick Start.
  • The user has interacted with the page. Until the session has as many actions as the model asks for, it is not sufficient and the result is 'insufficient'. With the built-in model that is 20 in a desktop browser, from at least two kinds of input (pointer, scroll, keyboard) with at least three each, and 8 in a browser on a phone or tablet. Right after page load there are none — see Evidence.

Usage

Read the classification

import { DeaSdk } from '@dea/sdk';

switch (DeaSdk.current?.getClassification().result) {
  case 'human':
    // Allow the action.
    break;
  case 'bot':
    // Block it, or take your strictest path.
    break;
  default:
    // 'undetermined', 'insufficient', or no SDK: take your fallback path.
}

getClassification() compares the session's score with the two thresholds of the loaded model:

Result When
'insufficient' Not enough evidence yet, or the SDK is still loading or could not load. There is no score: value is null
'human' The score is at or above humanThreshold. A model that sets no humanThreshold has one bar: at or above botThreshold is 'human'
'bot' The score is below botThreshold
'undetermined' The score is between the two thresholds

Your app decides what each result allows. 'insufficient' and 'undetermined' are different answers: the first is "too early", the second "not sure". The same call returns the score (value), how many scored actions stand behind it (actions), both thresholds and the modelVersion they come from. How scoring works explains each of them.

If the loaded model has no bot threshold, getClassification() throws ThresholdMissing — see Troubleshooting.

Check how much evidence has been collected

sufficiency() reports what the session has collected so far: how long it has run and how many actions of each kind of input. getClassification() already says 'insufficient' while there is not enough; use sufficiency() to see what is missing, for example to delay a challenge until the user has had a chance to interact.

import { DeaSdk } from '@dea/sdk';

const s = DeaSdk.current?.sufficiency();

if (s === null || s === undefined) {
  // No SDK, or its scoring engine is not running yet: "no answer yet", not "not enough evidence".
} else if (!s.sufficient) {
  console.log(`Collected ${s.actions} actions over ${s.durationMs} ms — not enough yet`);
}

Examples

Gate a sign-up form

import { init, DeaSdk } from '@dea/sdk';

init({ appId: 'YOUR_APP_ID', appKey: 'YOUR_APP_KEY' });

document.querySelector<HTMLFormElement>('#sign-up')!.addEventListener('submit', async (event) => {
  event.preventDefault();

  if (DeaSdk.current?.getClassification().result === 'human') {
    await fetch('/api/sign-up', { method: 'POST', body: new FormData(event.currentTarget as HTMLFormElement) });
  } else {
    showCaptcha();
  }
});

showCaptcha stands for your own fallback.

React

import { DeaSdk } from '@dea/sdk';

export function ClaimRewardButton({ onClaim }: { onClaim: () => void }) {
  const handleClick = () => {
    if (DeaSdk.current?.getClassification().result === 'human') {
      onClaim();
    } else {
      openVerificationDialog();
    }
  };

  return <button onClick={handleClick}>Claim reward</button>;
}

openVerificationDialog stands for your own fallback.

API

Member Returns Description
getClassification() Classification 'human', 'bot', 'undetermined' or 'insufficient', with the score and the thresholds behind it
sufficiency() Sufficiency \| null Evidence collected so far; null while the scoring engine is not running
ready() Promise<void> Resolves once the SDK has finished loading, successfully or not
error Error \| null Why the SDK cannot produce a classification, if it cannot