Integration Guide
Widget setup, server-side verification, and migration notes for existing CAPTCHA deployments.
Quick Start
BotFlush can be integrated in 3 steps: load the widget, render it, and verify tokens server-side.
1. Load the Widget
Add the widget script to your page. It loads asynchronously and won't block rendering.
<script src="https://challenge.botflush.com/widget.js" async defer></script>
2. Add the Container
Place a container element where you want the CAPTCHA checkbox to appear.
<div id="bf-captcha" data-sitekey="YOUR_SITE_KEY"></div>
3. Verify Server-Side
When the user completes the challenge, a token is generated. Send it to your server and verify via API.
POST https://challenge.botflush.com/api/siteverify
Content-Type: application/json
{
"secret": "YOUR_SECRET_KEY",
"token": "TOKEN_FROM_CLIENT"
}
Response:
{
"success": true,
"site_key": "YOUR_SITE_KEY",
"timestamp": "2026-04-15T12:00:00Z"
}
JavaScript API
BotFlush.render()
Programmatically render the widget into a container element.
BotFlush.render('bf-captcha', {
siteKey: 'YOUR_SITE_KEY',
callback: function(token) {
// Token received — send to your server
console.log('Verified:', token);
},
'expired-callback': function() {
// Token expired — prompt user to re-verify
},
'error-callback': function() {
// Error occurred
}
});
BotFlush.reset()
Reset the widget to its initial state. Useful after form submission.
BotFlush.reset();
BotFlush.getResponse()
Get the current verification token string. Returns empty string if not yet verified.
var token = BotFlush.getResponse();
Existing CAPTCHA Migration
BotFlush supports a migration path for common checkbox-style CAPTCHA integrations. Exact changes depend on how your application uses callbacks, errors, and backend verification.
| Legacy CAPTCHA | BotFlush | |
|---|---|---|
| Widget Script | legacy-captcha.example/api.js |
challenge.botflush.com/widget.js |
| Verify Endpoint | legacy-captcha.example/api/siteverify |
challenge.botflush.com/api/siteverify |
| Site Key | Previous provider key | BotFlush key from Console |
| Container class | captcha-widget |
BotFlush container attributes |
| Callback params | data-callback |
data-callback supported |
Migration Example
Change your existing CAPTCHA integration:
<!-- Before (existing CAPTCHA) -->
<script src="https://legacy-captcha.example/api.js"></script>
<div class="captcha-widget" data-sitekey="LEGACY_SITE_KEY"></div>
<!-- After (BotFlush) -->
<script src="https://challenge.botflush.com/widget.js"></script>
<div class="captcha-widget" data-sitekey="BOTFLUSH_KEY"></div>
Server-side: update the verification endpoint from legacy-captcha.example/api/siteverify to challenge.botflush.com/api/siteverify. The verify endpoint is designed to return familiar success and error fields; validate any app-specific error handling during migration.
Privacy and Data Controls
BotFlush is designed around privacy-minded defaults and minimized data use. Review your own deployment, account settings, and data processing agreement for the data processing details that apply to your use case.
Enabling Strict GDPR Mode
For sites serving EU users that require explicit consent flows:
- Log in to the BotFlush Console
- Navigate to the site settings for your domain
- Enable the available privacy mode for the site
- This limits optional analytics and cookie use according to the configured mode
Availability may depend on plan and deployment. The console remains the source of truth for currently available privacy and data controls.
Verification Modes
BotFlush offers multiple challenge engines. You can configure which engines to use per-site in the Console.
| Engine | Type | Description |
|---|---|---|
| Invisible Free | Background | Zero-interaction proof-of-work challenge |
| Visual Match | Interactive | Image pattern matching challenge |
| Emoji Click | Interactive | Select matching emoji from a visual grid |
| Invisible Pro | Background | Advanced behavioral analysis |
| Invisible Max | Background | GPU-accelerated proof-of-work |
| Text Challenge | Interactive | Localized text-based verification |
Server-Side Verification
The verify endpoint accepts a standard POST request. Select a server runtime to view the corresponding example.
const response = await fetch('https://challenge.botflush.com/api/siteverify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
secret: process.env.BOTFLUSH_SECRET,
token: req.body['bf-token']
})
});
const result = await response.json();
if (!result.success) {
return res.status(403).send('Verification failed');
}
import requests
response = requests.post('https://challenge.botflush.com/api/siteverify', json={
'secret': BOTFLUSH_SECRET,
'token': request.form['bf-token'],
})
if not response.json().get('success'):
abort(403)
$payload = json_encode([
'secret' => getenv('BOTFLUSH_SECRET'),
'token' => $_POST['bf-token'] ?? ''
]);
$context = stream_context_create(['http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => $payload,
]]);
$response = file_get_contents('https://challenge.botflush.com/api/siteverify', false, $context);
$result = json_decode($response, true);
if (empty($result['success'])) { http_response_code(403); exit; }
payload, _ := json.Marshal(map[string]string{
"secret": os.Getenv("BOTFLUSH_SECRET"),
"token": r.FormValue("bf-token"),
})
resp, err := http.Post("https://challenge.botflush.com/api/siteverify",
"application/json", bytes.NewBuffer(payload))
if err != nil { http.Error(w, "verify failed", 502); return }
defer resp.Body.Close()
var result struct{ Success bool }
json.NewDecoder(resp.Body).Decode(&result)
if !result.Success { w.WriteHeader(http.StatusForbidden); return }
HttpClient client = HttpClient.newHttpClient();
String body = """
{
"secret": "%s",
"token": "%s"
}
""".formatted(System.getenv("BOTFLUSH_SECRET"), token);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://challenge.botflush.com/api/siteverify"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
Map<String, Object> result = new ObjectMapper().readValue(response.body(), Map.class);
if (!Boolean.TRUE.equals(result.get("success"))) {
throw new SecurityException("Verification failed");
}
using var client = new HttpClient();
var payload = new {
secret = Environment.GetEnvironmentVariable("BOTFLUSH_SECRET"),
token = Request.Form["bf-token"].ToString()
};
var response = await client.PostAsJsonAsync(
"https://challenge.botflush.com/api/siteverify",
payload);
var result = await response.Content.ReadFromJsonAsync<VerifyResult>();
if (result?.Success != true) {
return Forbid();
}
Downloads
Node Inspector — Chrome Extension
Inspect which BotFlush service endpoint served a verification challenge on websites that use BotFlush. A small badge appears at the bottom-right corner showing the endpoint URL.
Installation: Download and unzip → Chrome → chrome://extensions → Enable Developer Mode → Load Unpacked → select the folder.