Skip to content

Install with an AI assistant

This page is the canonical install reference for people and for AI coding assistants. Every package name, import and option below exists in the published packages. If a snippet you were given elsewhere uses a name that is not on this page, it is wrong.

A machine-readable index of these docs is at docs.webdecoy.com/llms.txt, and the full text is at llms-full.txt.

The best path: connect the assistant to WebDecoy

Section titled “The best path: connect the assistant to WebDecoy”

If your assistant supports MCP (Claude Code, Claude.ai, ChatGPT, Codex, Cursor and others), connect it to WebDecoy’s hosted MCP server at https://mcp.webdecoy.com/mcp. Its get_install_guide tool returns the install steps for your stack with your site’s public IDs already filled in, and get_install_status proves the install is reporting. Nothing has to be copied by hand.

In Claude Code:

/plugin marketplace add WebDecoy/claude-plugins
/plugin install webdecoy@webdecoy

Then run /webdecoy:install. For every other assistant, follow Connect an AI assistant.

Without MCP, paste this into ChatGPT, Claude, Cursor, Copilot or any other assistant working in your codebase:

Install WebDecoy bot detection in this project.
1. Read https://docs.webdecoy.com/installation/install-with-ai/ and use only the
package names, imports, options and environment variables shown there.
Do not invent any other WebDecoy package, option or variable.
2. Detect this project's stack and pick the matching section. If none matches,
use the browser detection script.
3. Leave WebDecoy in its default monitor mode. Do not set mode: 'enforce'.
4. Never write a secret into the code or a committed file. Read secrets from
environment variables, tell me each variable's name and where to create its
value, and let me set it myself.
5. Tell me how to verify the install, using the test request on that page.

Most installs need a free account at app.webdecoy.com and a site in it. Where a step needs a value from the dashboard:

Value Where it comes from Secret?
WEBDECOY_API_KEY (sk_live_...) API Keys in the dashboard Yes
data-aid, data-sid on the script tag Detection Scripts, Copy snippet No
WEBDECOY_SITE_KEY, WEBDECOY_SCANNER_ID The platform’s step in Setup No
WEBDECOY_SENSOR_KEY The platform’s step in Setup Yes

The Node packages do not read WEBDECOY_API_KEY by themselves. Pass it as apiKey, as every snippet below does. Without an apiKey the Node middleware still runs its local rules (the tripwire by default, and any rate limits you configure), but nothing reports to your dashboard.

Every Node framework adapter starts in monitor mode: it records verdicts and serves every request. Switch to mode: 'enforce' only after you have reviewed what it would have blocked.

Your stack Install Code change?
Next.js @webdecoy/nextjs Yes
Express @webdecoy/express Yes
Fastify @webdecoy/fastify Yes
Hono (Workers, Bun, Deno, Node) @webdecoy/hono Yes
Any other Node.js server @webdecoy/node Yes
WordPress The webdecoy plugin No
Shopify The WebDecoy Shopify app No
Cloudflare One-click edge sensor No
Vercel Integration (log drain), optional middleware No, or one file
Netlify Extension plus environment variables No
PHP (Laravel, Symfony, plain PHP) composer require webdecoy/sensor Yes
Anything else A script tag One line of HTML
Terminal window
npm install @webdecoy/nextjs @webdecoy/node
// middleware.ts (project root, or src/ if you use it)
import { withWebDecoy } from '@webdecoy/nextjs';
export default withWebDecoy({
apiKey: process.env.WEBDECOY_API_KEY!,
});
// Protect the routes that matter and leave static assets alone.
export const config = {
matcher: ['/api/:path*', '/checkout/:path*'],
};

Details: Next.js middleware. To refuse scrapers on chosen paths with a clearance token instead, see Vercel middleware (clearance).

Terminal window
npm install @webdecoy/express @webdecoy/node
import express from 'express';
import { webdecoy } from '@webdecoy/express';
const app = express();
app.use(webdecoy({
apiKey: process.env.WEBDECOY_API_KEY,
skipPaths: ['/health'],
}));
app.get('/', (req, res) => {
// req.webdecoy carries the detection (decision, confidence, threat_level, bot_detected)
res.send('ok');
});

Mount it before your routes. Behind a proxy, pass trustProxy (a hop count, 'cloudflare', 'railway', or your proxies’ CIDRs). Details: Express middleware.

Terminal window
npm install @webdecoy/fastify @webdecoy/node
import Fastify from 'fastify';
import webdecoy from '@webdecoy/fastify';
const app = Fastify();
await app.register(webdecoy, {
apiKey: process.env.WEBDECOY_API_KEY,
skipPaths: ['/health'],
});
// request.webdecoy carries the detection on every route

Behind a proxy, pass trustProxy to the WebDecoy plugin, not to Fastify. Details: Fastify plugin.

Terminal window
npm install @webdecoy/hono @webdecoy/node
import { Hono } from 'hono';
import { webdecoy } from '@webdecoy/hono';
const app = new Hono();
app.use('*', webdecoy({
apiKey: process.env.WEBDECOY_API_KEY,
skipPaths: ['/health'],
}));
app.get('/', (c) => {
// c.get('webdecoy') carries the decision; in monitor mode this is where it surfaces
return c.text('ok');
});
export default app;

On Cloudflare Workers, process.env needs the nodejs_compat compatibility flag and a recent compatibility date. Behind Cloudflare, trustProxy: 'cloudflare' is stronger than the default of one trusted hop.

For any other fetch-style runtime (Bun, Deno, Astro, SvelteKit, Remix), createFetchGuard() from @webdecoy/node is the same implementation the Hono adapter wraps:

import { createFetchGuard } from '@webdecoy/node';
const guard = createFetchGuard({ apiKey: process.env.WEBDECOY_API_KEY });
export default {
async fetch(request: Request): Promise<Response> {
const { response } = await guard.check(request);
if (response) return response; // only ever set in enforce mode
return guard.decorate(await handle(request)); // handle() is your app
},
};
Terminal window
npm install @webdecoy/node
import http from 'node:http';
import { WebDecoy } from '@webdecoy/node';
const wd = new WebDecoy({ apiKey: process.env.WEBDECOY_API_KEY });
http.createServer(async (req, res) => {
const decision = await wd.protect({
method: req.method,
path: new URL(req.url, 'http://localhost').pathname,
ip: req.socket.remoteAddress ?? '',
user_agent: req.headers['user-agent'],
headers: Object.fromEntries(
Object.entries(req.headers).map(([name, value]) => [name, String(value)])
),
timestamp: Date.now(),
});
// protect() returns a decision and blocks nothing itself.
// Log decision.conclusion ('ALLOW', 'DENY', 'CHALLENGE' or 'ERROR') first;
// refuse with a 403 when decision.allowed is false only once you are ready.
res.end('ok');
}).listen(3000);

protect() fails open: if WebDecoy cannot be reached, allowed is true. Behind a proxy, use resolveClientIp() from the same package to get the real client address. Details: Node.js SDK.

Terminal window
wp plugin install webdecoy --activate

Or in WordPress Admin: Plugins, Add New, search WebDecoy, Install Now, Activate. It runs locally with no account or API key and starts in monitor mode. Details: WordPress plugin.

Install the WebDecoy app from the Shopify App Store, then enable the WebDecoy Bot Detection app embed in your published theme. There is no code to add and no separate WebDecoy login. Details: Shopify app.

If your traffic is proxied through Cloudflare (orange cloud), install the edge sensor from the dashboard. There is no code and no package:

  1. Open Integrations, Cloudflare and choose Connect with Cloudflare.
  2. Open Edge Sensor, pick the zone and route, and choose Deploy edge sensor.

It sees crawlers that never run JavaScript. Details: Cloudflare edge sensor.

For reporting with no code change, install the WebDecoy Vercel integration. It sets up a log drain and needs a Vercel Pro or Enterprise team. Details: Vercel integration.

To refuse scrapers on chosen paths, add the clearance middleware. Set WEBDECOY_SITE_KEY, WEBDECOY_SCANNER_ID and WEBDECOY_SENSOR_KEY from Enforcement, Setup in the Vercel project, then:

// middleware.ts, Next.js
import { withClearance } from '@webdecoy/nextjs';
export default withClearance();
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
};
// middleware.ts, Astro, SvelteKit, Nuxt, Remix or a static site
export { default } from '@webdecoy/node/vercel';

It follows the site’s WebDecoy mode, monitor until you switch it. Details: Vercel middleware (clearance).

  1. Install the WebDecoy Crawler Sensor extension on your Netlify team.
  2. Add WEBDECOY_SITE_KEY, WEBDECOY_SCANNER_ID and WEBDECOY_SENSOR_KEY (from the site’s Setup page, Netlify step) as site environment variables with the Functions scope.
  3. Trigger a deploy.

Details: Netlify extension.

Terminal window
composer require webdecoy/sensor
<?php
// Early in your front controller (for example public/index.php), after Composer's autoloader.
use WebDecoy\Sensor\{Sensor, Config, Request};
$sensor = new Sensor(Config::fromEnvironment()); // reads WEBDECOY_API_KEY
$request = Request::fromGlobals();
// Report after the response is on its way. observe() never throws.
register_shutdown_function(static fn () => $sensor->observe($request));

Behind a CDN or load balancer, set WEBDECOY_TRUSTED_PROXIES to your proxies’ CIDRs (comma separated), or every visitor looks like your proxy. Requires PHP 8.1 or later with ext-curl and ext-json. It is a sensor: it reports and never blocks. Framework middleware and auto_prepend_file setups are in the package README. For WordPress use the plugin instead.

For any site where you can edit the HTML. Copy the generated line from Detection Scripts in the dashboard and paste it before </head> in your shared layout:

<script
async
src="https://cdn.webdecoy.com/bot-detection/v1/bot-detection.min.js"
data-aid="your-property-uuid"
data-sid="your-scanner-uuid">
</script>

Do not assemble the IDs by hand: data-aid is the site’s property ID and data-sid is the detection script ID. A script tag cannot see clients that never run JavaScript, such as GPTBot or curl. Details: Browser detection script.

For server installs (Node packages, PHP, Netlify, the Cloudflare edge sensor), send one request with the reserved test User-Agent:

Terminal window
curl -A "WebDecoy-Test/1.0" http://localhost:3000/

Send it to a path your middleware actually runs on. With the Next.js snippet above, the matcher covers only /api/* and /checkout/*, so use a route such as http://localhost:3000/api/health instead of /. The test request reports only when an apiKey is passed.

A detection labeled Test appears on the Detections page within a few seconds. Test detections are excluded from stats and billing. For the script tag, load a page that carries it and watch Sensors. For every method, see Verify your install.

  • Do not install packages that are not on this page. WebDecoy has no Go, Python or NestJS bot-detection SDK; the Node packages are @webdecoy/node, @webdecoy/express, @webdecoy/fastify, @webdecoy/nextjs, @webdecoy/hono and @webdecoy/client. (The separate AI Protection SDKs are a different product.)
  • Do not commit WEBDECOY_API_KEY or WEBDECOY_SENSOR_KEY.
  • Do not turn on mode: 'enforce' as part of the install.