> For an index of all Botscent documentation, see https://botscent.nibnalin.me/llms.txt.

# 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](/docs/script-tag), [React](/docs/react), [Vue](/docs/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.

```sh title="Terminal"
npm install botscent
```

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

For Python, install `botscent` from PyPI.

```sh title="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`:

```ts title="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`:

```python title="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](/docs/server-to-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](/docs/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:

```ts title="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](/docs/verdict).

In Python, the same functions have snake_case names:

```python title="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](/docs/trust-model).

## 5. Check the install

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

```sh title="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](/docs/verify).

## Next steps

* [Server API (TypeScript)](/docs/server-api#inspect): every option of `inspect`.
* [Server API (Python)](/docs/python-api#botscentinspect): the Python `inspect` and its arguments.
* [From the page to the server](/docs/page-to-server): join a page report to the request's own verdict.
