Skip to content

Fastify Plugin

@webdecoy/fastify registers the Node SDK as a Fastify plugin. Detection runs on every request, blocked requests get a 403 by default, and the result is attached to req.webdecoy.

For package capabilities and positioning, see the Fastify bot detection product page.

Terminal window
npm install @webdecoy/fastify @webdecoy/node
import Fastify from 'fastify';
import webdecoyPlugin from '@webdecoy/fastify';
const fastify = Fastify();
await fastify.register(webdecoyPlugin, {
threshold: 70,
skipPaths: ['/health']
});
fastify.post('/api/checkout', async (req, reply) => {
const { decision, confidence, bot_detected } = req.webdecoy;
if (decision === 'block') {
return reply.code(403).send({ error: 'Request blocked' });
}
if (decision === 'challenge') {
return reply.code(429).send({ error: 'Verification required' });
}
// Process checkout...
});

Send one request with the reserved test User-Agent. It always fires a detection through the real pipeline, works on localhost before you deploy, and shows up labeled Test in the dashboard (excluded from stats and billing):

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

Within a few seconds a detection with the Test category chip appears on the Detections page. If nothing appears, check that the plugin is registered before your routes and that WEBDECOY_API_KEY is set.

Extends the core ProtectOptions (threshold, skipLocalAnalysis, metadata) with:

Option Default Description
getIP request.ip (set Fastify’s trustProxy for x-forwarded-for) Custom IP extraction
onBlocked 403 Forbidden Custom handler for blocked requests
onError Log and allow (fail open) Custom error handler
skipPaths None Paths to skip
rules None Local rules such as tripwire()
honeytoken true when apiKey is set Inject a hidden trap link into HTML replies

With an apiKey, this is already on. The plugin injects a hidden honeytoken link into your HTML replies and arms the tripwire it points at:

import Fastify from 'fastify';
import webdecoy from '@webdecoy/fastify';
const app = Fastify();
await app.register(webdecoy, { apiKey: process.env.WEBDECOY_API_KEY });

The path is derived from your API key by HMAC, so every replica advertises and arms the same one. Set honeytoken: false to opt out.

Injection happens in an onSend hook and only rewrites full text/html replies, so JSON, text and downloads are untouched and Fastify recomputes Content-Length for you.

webdecoyCaptchaPlugin mounts the self-hosted captcha endpoints for the Browser Client widget:

import { webdecoyCaptchaPlugin } from '@webdecoy/fastify';
await fastify.register(webdecoyCaptchaPlugin, {
secret: process.env.WEBDECOY_SECRET
});

  • Node SDK: the core API, configuration, and detection response
  • Browser Client: the widget for the captcha endpoints