How scoring works
How Botardo turns a session into allow or block, when a visitor is challenged, and what drives the bot risk behind it.
Every time you verify a token, we answer allow or block. Behind that sits a bot risk from 0 (a person) to 100 (a bot). Every session starts at 100 — see why sessions start at 100 — and only moves down as signal layers confirm the session looks human. Here's how we get from a session to an answer.
A session is one browser tab. It starts when the snippet loads, carries on across the pages that tab opens on your site, and lasts up to three hours. A new tab, even one opened from a link, starts a new session. Each time you ask for a token, we score everything we've received from the session so far.
Signal layers
Botardo evaluates sessions across three independent signal layers. Each layer holds a portion of the starting 100 and releases it when it finds evidence consistent with a human; a layer that never reports simply never releases its share, and the risk stays high.
Behavior
How the visitor moves, scrolls and types over the visit. We never record which keys are pressed or what anyone types. Input that looks like a person lowers the risk; machine-like input, or no interaction at all, leaves it unchanged.
Network
Where the connection comes from and how it was made. Most people arrive from home or mobile networks, which lowers the risk.
Environment
Whether the browser is an ordinary browser, and really the browser it says it is. A real, fully featured browser lowers the risk. Headless browsers keep their tells even when they pretend to be something else, so this layer doesn't release its share for them.
From a session to an answer
When you ask for a token, the session lands in one of three places:
| What we see | What happens | What your server gets |
|---|---|---|
| Enough evidence that it's a person | The token is issued straight away. | allow |
| We can't tell yet, or there wasn't much to go on | The visitor is challenged before the token exists, as many times as it takes. Once the visitor passes, the token is issued. | allow, once they pass |
| Clear signs of automation | The token is issued, quietly. | block |
A high risk on its own never gets a session blocked. If we're not sure, we ask for proof instead. A bot that can't pass the challenge never gets a token, so it never reaches your server with one.
Botardo never blocks anyone on its own. The decision is advice; your server acts on it.
A missing, expired or already used token gets block too, with a status that says which. A bot that skips the snippet sends no token at all, so letting those through would let any bot in.
Strictness
Each site has a strictness setting in the Console: relaxed, balanced (the default) or strict. It changes how readily we ask for proof: relaxed challenges fewer visitors, strict challenges more. It never changes what gets blocked. Changing it takes effect on the next token, with no deploy.
Monitor mode
With monitor mode on, verify answers allow to everything, no visitor is challenged, and the Console shows what we would have done. Turn it on for your first week to see how your real visitors fare, then switch to enforcing when you're happy.
Using risk
decision is all you need to protect a request. risk is there for logging, and for extra care on actions where you'd rather be cautious, such as a payout or a password change:
const { decision, risk } = await sentinel.verify(token);
if (decision === "block") return reject();
if (risk > 25) await requireEmailCheck(user); // extra care, not a rejection
Don't turn people away on risk alone. A visitor who just passed our challenge has already proved themselves, even if their risk isn't zero. If you want fewer borderline sessions let through, raise the site's strictness instead.
What verify doesn't tell you
Verify returns a decision and a risk, and nothing else. We don't say which layer or signal led to them, to you or to anyone. Every explanation would be a hint for whoever builds the next bot.