Custom Stack
One module, one call, any JavaScript server
Not on WordPress and not behind Cloudflare? Drop a dependency-free ES module into your app and call it once per request. It buffers the AI-crawler visits it sees and flushes them to Baseline on its own. It imports nothing, and it cannot touch a byte of your responses.
A reference implementation you own
The WordPress plugin and the Cloudflare worker speak a contract. This is that contract written out as one readable file, rendered with your site token. You are not integrating against a black box - you can read every line of it before it goes near your server.
observe() returns nothing and takes plain values. It is given no handle on a response, so it cannot change a body, a header or a status even by accident. Reading the user agent to decide what to report is the feature; letting it change output would be cloaking.
One file, no imports, no build step, no package to audit. Copy it into your project and it works wherever fetch does.
It batches to 500 hits on a 60-second timer and refuses to grow past 5,000 buffered, counting the excess as dropped rather than eating memory. A failed flush never reaches your request path.
Its bot matcher over-matches deliberately. The authoritative registry lives on our server and discards anything that is not an AI crawler, so a wasted row costs nothing while a missed one is gone for good.
Wire it in, step by step
Five steps. Two of them are copy buttons, and one of them your coding agent can do for you.
-
Name the site you are connectingWe do not guess this. Registering the site named above is what mints the ingest token the module presents on every batch, and what your ownership tag is derived from.
-
Get the modulePre-filled with your domain and your ingest token. Register the domain above and it appears here.
-
Call it once per requestSave it into your project and call
observe(req, status)as early as your framework lets you see a request, once the status code is known. It batches and flushes on its own; there is nothing to await and nothing to shut down.// Express import { observe } from "./baseline-report-bot-hits.js"; app.use((req, res, next) => { res.on("finish", () => observe(req, res.statusCode)); next(); }); // A fetch-style handler (Deno, Bun, Workers, Next.js middleware) const res = await handle(request); observe(request, res.status); return res;
Or let your coding agent do it
Connect the Baseline MCP, then ask your agent to add AI-bot tracking for this domain. It registers the site, pulls this same module and writes it into your project.
An agent with your repo does the whole job. A chat client cannot. Claude Code or Cursor has your files and installs it. Claude.ai or ChatGPT has no filesystem, so it hands you the code to paste - and the ingest token then lives in that conversation history, on someone else's servers. That is a real exposure and it is worth knowing before you pick the door: whoever holds the token can post fabricated crawler hits for this one site. It reads nothing, reaches no other site, and spends no credits.
-
Emit your ownership tagThe module reports crawler hits; it does not touch your HTML, deliberately. So proving you own the domain is one tag you add yourself, server-side, wherever you render
<head>. It has to be in the HTML your server returns - a script that adds it in the browser is too late for us and for crawlers. -
Check it from our sideYour logs will tell you the module ran. This tells you what actually reached Baseline, which is the answer that counts. It answers for the site named at the top of this walkthrough.
Three things this module refuses to do
Vary: User-Agent, no cache-bypass header for bots. That is the obvious fix for the cache blind spot above, and it is cloaking wearing a header - bots would get freshly rendered HTML while people get a cached copy, and those differ on any page with a timestamp or a nonce.What you need
| Runtime | Any JavaScript server with a global fetch: Node 18+, Deno, Bun, or an edge runtime. |
|---|---|
| Account | A free Baseline Labs account. Sign up - no card. |
| Crawler reporting | Free, on every plan. |
| Schema injection | Not offered by this channel - the module never touches your HTML. To inject schema server-side, use the Cloudflare worker or the WordPress plugin. |
| Outbound network | Your server needs to reach api.baselinelabs.ai over HTTPS. |
There are two ready-made ways in
If one of these fits your stack it is less work than wiring a module in by hand, and both also inject schema.
See which AI crawlers read you
One file, one call per request, and your dashboard starts filling with the crawlers that were already visiting.