This guide adds an Express middleware that blocks bots using an explainable verdict from detectip.ai. The browser is fingerprinted by the collector tag; your server fetches a verdict by session token and acts on the recommended action. See the live demo for what the verdict contains.
1. Add the collector tag
On your pages, before </body>:
<script src="https://detectip.ai/collector.js" data-key="pk_live_..."></script>
It sets a first-party botd_token cookie.
2. The middleware
Keep your secret key in an environment variable. Use a short timeout and fail open so detection never breaks the app:
import express from "express";
import cookieParser from "cookie-parser";
const app = express();
app.use(cookieParser());
async function botGuard(req, res, next) {
const token = req.cookies.botd_token;
if (!token) return next();
try {
const ctrl = new AbortController();
const t = setTimeout(() => ctrl.abort(), 2000);
const r = await fetch(
`https://detectip.ai/api/v1/verdict?token=${encodeURIComponent(token)}`,
{ headers: { "X-API-Key": process.env.DETECTIP_KEY }, signal: ctrl.signal }
);
clearTimeout(t);
if (r.ok) {
const v = await r.json();
if (v.action === "block") return res.status(403).send("Forbidden");
if (v.action === "challenge") return res.redirect("/challenge");
}
} catch (_) {
// fail open on timeout / network error
}
next();
}
3. Apply it to sensitive routes
app.post("/api/register", botGuard, (req, res) => { /* ... */ });
app.post("/api/login", botGuard, (req, res) => { /* ... */ });
app.post("/api/comment", botGuard, (req, res) => { /* ... */ });
4. Prefer the official client (optional)
The Go client wraps this with typed helpers (v.ShouldBlock(), v.ShouldChallenge()) and error states. If your backend is Go, see the docs; for Node, the fetch above is all you need.
Why act on action, not just score
The server computes action (allow/challenge/block) from your configured thresholds, so enforcement stays consistent across services. You can still read score and band for logging. Background: how to filter bots from web traffic.
FAQ
Will it block search engines? No — declared crawlers are verified by reverse DNS and not flagged as fake.
Latency? The 2s AbortController + try/catch fails open; gate only high-value POSTs, not every request.
Get a key: free tier at signup; full reference in the API docs.