SilentShield

Integrate SilentShield securely into your form

Client script, server-side verification, keys and error cases – the complete integration in one place.

How the script and the server check work together

A complete integration has two halves: the script in the browser and a check on your server.

  1. 1

    Script loads

    Your page loads client.js?k=… with your site key. The script measures behaviour in the form.

  2. 2

    Form is submitted

    On submit, the script reports the measurement and adds the field behavior_nonce to your form.

  3. 3

    Your server asks

    Your server sends behavior_nonce to POST /api/v1/captcha/verify-nonce, with your key in the X-Api-Key header.

  4. 4

    You decide

    The response contains ok, verdict, confidence and reason_codes. Accept the submission if ok is true, otherwise reject it.

Without step 3 the integration only protects half the way: the script alone does not stop a request sent directly to your server.

Site key and server key

Site key (public)

client.js?k=…

It appears in your page source and is visible to anyone. It binds the script to your domain; subdomains such as www. or staging. are included.

Server key (secret, optional)

X-Api-Key

Optional. If you want the calls your server makes to carry a value that is not in your page source, create it in the dashboard on the key, in the “Server key” tab. It belongs on your server only, never in the browser, and can be regenerated at any time.

The server check works with the site key alone, so you do not need to change anything. Both keys are accepted. With the server key, your server code contains no value that anyone can read in your page source.

Quickstart

1

Install & Embed

Add the script and get a token

2

Verify on Server

Validate the token on your backend

Quick Test with cURL

Verify nonce from command line

# Verify Nonce
curl -X POST https://api.silentshield.io/api/v1/captcha/verify-nonce \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"nonce": "256ea6c63c3ccdd317e05cbc9ef0c659"}'

Frontend Integration

Add the client script with SRI and defer attributes

<!-- In <head> or before </body> of every page with a form -->
<script src="https://api.silentshield.io/client.js?k=YOUR_API_KEY" defer></script>

Security & Privacy

  • No cookies – fully cookieless operation
  • No profiles, no cookies – can be used in a GDPR-compliant way
  • EU hosting – checks and storage on our servers in Germany
  • WCAG compliant – accessible to all users
  • CSP compatible – use with Content Security Policy:
Content-Security-Policy: script-src 'self' https://api-us.silentshield.io https://api-eu.silentshield.io; connect-src 'self' https://api-us.silentshield.io https://api-eu.silentshield.io; worker-src 'self' blob:;

SDKs & Libraries

The package runs on your server (Node.js 18 or newer). In the browser you need no package at all — the client.js snippet from the quick start does the job.

Node.js / Express

v1.5.0
npm i @forge12interactive/silentshield-sdk-js
import { createClient } from "@forge12interactive/silentshield-sdk-js";

const shield = createClient({ apiKey: process.env.SILENTSHIELD_API_KEY });

app.post("/signup", async (req, res) => {
  const { human } = await shield.verify(req.body.behavior_nonce);
  if (!human) return res.status(403).send("Verification failed");
  res.send("ok");
});

AI agents (Node.js)

v1.5.0
npm i @forge12interactive/silentshield-sdk-js
import { createClient, enforce } from "@forge12interactive/silentshield-sdk-js";

const shield = createClient({ apiKey: process.env.SILENTSHIELD_API_KEY });

// Reports bot candidates only — never blocks, never sees human traffic.
app.use(shield.observe);

// Applies your policy locally from a signed bundle. Fail-open.
app.use(enforce({ apiKey: process.env.SILENTSHIELD_API_KEY }));

API Reference

API Version: 2025-10-01 · Base URL: https://api.silentshield.io

POST/api/v1/captcha/verify-nonce

Verify SilentShield Nonce

Request Headers:

X-Api-KeyYOUR_API_KEY
Content-Typeapplication/json

Request Body:

noncestringThe nonce to verify

Response:

Success (200):

{
  "ok": true,
  "verdict": "human",
  "confidence": 0.95,
  "requested_nonce": "256ea6c63c3ccdd317e05cbc9ef0c659"
}

Error:

{
  "ok": false,
  "verdict": "bot",
  "confidence": 0.12,
  "request_nonce": "256ea6c63c3ccdd317e05cbc9ef0c659",
  "reason_codes": ["NO_MOUSE_MOVEMENT"]
}

Status Codes:

200Nonce successfully verified
400Invalid request (missing or incorrect nonce)
401Invalid API Key
403Not confirmed as human (ok: false) – reject the submission
429Rate limit exceeded
500Internal Server Error

Timeouts, outages and quota

  • Set a timeout for the server check. Our code examples use 5 seconds.
  • If the check does not answer in time, the examples treat it as “not confirmed” and reject. If you prefer to accept in that case, catch the error yourself — the decision is yours.
  • If the first host does not answer while the script loads its settings and components, it falls back to the second (api.silentshield.io and api-eu.silentshield.io). Keys with strict EU binding stay on the EU host.
  • There is no automatic fallback host for the server check.
  • Above your monthly quota, the API keeps checking and answers as usual. A 429 means that the per-minute rate limit for your key has been exceeded.

Testing locally and on a test domain

  • Your key does not work on localhost: it is bound to your domain, and the script is rejected there.
  • Test on a subdomain of your domain, for example staging.your-domain.com. It runs with the main domain's key and does not use another domain slot.
  • If you want to evaluate test and live separately, create a second key for the same domain. It does not use another domain slot either.
  • Submit a form as a test and check the verify-nonce response on your server: an entry typed by hand should return ok: true; otherwise the reason_codes show why not.
Set up a test domain

Versions and changes

  • The API carries its version in the path: /api/v1. The same routes are available under /api.
  • The script has no version number: client.js always delivers the current release, so there is nothing for you to update.
  • The SDKs for PHP, Node, Go and Edge have version numbers; changes are listed in each package's changelog.
  • We publish changes to the API and the script in the changelog.

Resources

Help Center

Comprehensive documentation with getting started guides, integration tutorials, configuration references, and troubleshooting.

Changelog

Stay up to date with the latest features, improvements, and fixes.

Ready to start?

Create a free account and get your key.