Skip to content
Botscent

Any other server

Call inspect on each request in a server that has no Botscent adapter, in TypeScript or Python.

Add the server half of Botscent to a server that has no Botscent adapter. Call inspect where a request arrives to get the request's own verdict. TypeScript uses inspect from botscent/server, and Python uses botscent.inspect. For the page half, see A script tag, React, Vue or the page for the framework your site uses.

Before you start

You need one of these:

  • Node.js 22.12 or later, Deno, Bun, Cloudflare Workers or Vercel, for TypeScript
  • Python 3.11 or later, for Python

1. Install the package

For TypeScript, install botscent from npm.

Terminal
npm install botscent

With pnpm, yarn or bun, use their add command.

For Python, install botscent from PyPI.

Terminal
pip install botscent

With uv or poetry, use uv add botscent or poetry add botscent.

2. Add the server half

Call inspect in the code that handles each request.

TypeScript

inspect takes a Fetch Request, or an object with headers. The object can also have method and url. The headers can be a Headers object or a plain object of header values.

In server.ts, pass Node's IncomingMessage to inspect:

server.ts
import { createServer } from 'node:http'
import { inspect } from 'botscent/server'

createServer(async (req, res) => {
  const verdict = await inspect(req)
  res.setHeader('content-type', 'application/json')
  res.end(JSON.stringify(verdict))
}).listen(3000)

Each response now contains the request's own verdict.

Python

botscent.inspect takes any object with a headers mapping, or a dict of headers. It reads request.method when the object has one. The call is synchronous.

In app.py, pass a dict of headers to botscent.inspect:

app.py
import botscent

verdict = botscent.inspect({"user-agent": "curl/8.7.1"})

verdict now holds the verdict for those headers.

What inspect does

inspect reads the headers, the method and the URL. It reads no body and makes no network request.

inspect does not send the verdict to the page. Only the adapters add the Server-Timing entry that carries the request's own verdict to the page half. For the details, see From the server to the page.

3. Add the page half

The server half reads only what each request declares. The page half finds agents that operate a browser, from inside the page. The page half comes from the npm package botscent.

If your server sends HTML, add <script defer src="/botscent.js"></script> to each page. Serve node_modules/botscent/dist/botscent.js at /botscent.js from your own origin. If a frontend framework renders your pages, add the page half there instead. The Quickstart lists every framework.

4. Read the verdict

Read type first, then agent_name and reasons. In verdict.ts, a user agent that declares ChatGPT-User gives this verdict:

verdict.ts
import { inspect, isVerified } from 'botscent/server'

const verdict = await inspect({ headers: { 'user-agent': 'ChatGPT-User/1.0' } })
// => { type: 'agent', agent_name: 'chatgpt-user', reasons: ['ua.declared-agent-token'] }
isVerified(verdict, 'chatgpt-user')
// => false

The user agent only declares the name, so isVerified is false.

Only a verified Web Bot Auth signature makes a named check true. For what each field means, see The verdict.

In Python, the same functions have snake_case names:

verdict.py
import botscent

verdict = botscent.inspect({"user-agent": "ChatGPT-User/1.0"})
# => {'type': 'agent', 'agent_name': 'chatgpt-user', 'reasons': ['ua.declared-agent-token']}
botscent.is_verified(verdict, "chatgpt-user")
# => False

To give an agent access, use isVerified or botscent.is_verified on the request's own verdict. Use no other field for access. See The trust model.

5. Check the install

Start the server. Then run the check against one of its pages.

Terminal
npx botscent check http://localhost:3000/

The page-script check prints pass, and the check exits with code 0. The server-half check prints unknown, because inspect sends no entry to the page. If a check fails, see Verify your install.

Next steps