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.