The whole integration is a <div>, a <script> and one server-to-server call.
1. Register a site
Each application and environment gets its own site. Against the hosted
service this is a button in the dashboard; against your own instance it is one
call with your ADMIN_TOKEN:
curl -s -X POST https://api.bollwark.eu/v1/sites \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"my-production-app"}'{
"site_key": "00000000-0000-0000-0000-000000000000",
"secret_key": "hex-encoded-secret",
"allowed_origins": [],
"policy": {}
}| Key | Where it goes |
|---|---|
site_key |
Public. Goes in your HTML. |
secret_key |
Private. Backend configuration only. |
The secret is shown once. No endpoint reads it back, so if you lose it, rotate it. A reveal would be silent; a rotation breaks the integration immediately and loudly, which is the behaviour you want from a lost credential.
2. Embed the widget
<form action="/signup" method="post">
<label>
Email
<input type="email" name="email" required>
</label>
<div data-sitekey="YOUR_SITE_KEY"></div>
<button type="submit">Create account</button>
</form>
<script src="https://api.bollwark.eu/v1/widget.js"></script>The widget writes a hidden captcha-token field into the enclosing <form>.
/v1/widget.js is the only URL to hardcode — it pulls its stylesheet, worker
and Argon2 bundle from a content-hashed directory pinned to that build.
3. Verify on your backend
Reject the submission unless /v1/verify returns 200 and
success: true.
curl -s -X POST https://api.bollwark.eu/v1/verify \
-H "Authorization: Bearer YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{ "token": "<captcha-token value>" }'{ "success": true, "failover": false, "risk": "low", "challenge_id": "…" }Challenges are single-use — a replayed challenge_id fails.
4. Start in monitor mode
Putting this in front of a form that already works? Register it with
"mode": "monitor". Every verdict is scored and logged exactly as it would be
in enforcement, but nobody is ever refused.
-d '{"name":"contact-form","policy":{"mode":"monitor"}}'Watch the dashboard for a week, then flip to enforce. The scoring is
identical in both modes, so none of the numbers move when you do.