Quick Start

Get up and running in under a minute.

1Create a Site

Sign in with your BenEgeDeniz ID and create a new site in the dashboard to get your sitekey and secret key.

2Add the Widget

Include the Forge script and place the widget div inside your form.

<script src="https://forge.benegedeniz.com/widget/forge.js" async defer></script>

<form action="/submit" method="POST">
    <div class="forge-captcha" data-sitekey="YOUR_SITEKEY"></div>
    <button type="submit">Submit</button>
</form>
3Verify Server-Side

When the form is submitted, send the token to our verification API with your secret key.

Client-Side

Automatic Rendering

The widget automatically renders on all elements with the forge-captcha class.

<div class="forge-captcha" data-sitekey="YOUR_SITEKEY"></div>
JavaScript API

For programmatic control, use the ForgeCaptcha global object.

// Programmatic rendering
const widgetId = ForgeCaptcha.render('#my-container', {
    sitekey: 'YOUR_SITEKEY',
    callback: function(token) {
        console.log('Verified:', token);
    },
    'error-callback': function() {
        console.log('Challenge failed');
    }
});

// Get the response token
const token = ForgeCaptcha.getResponse(widgetId);

// Reset the widget
ForgeCaptcha.reset(widgetId);
Data Attributes
Attribute Type Description
data-sitekeystringYour site's public key (required).
data-callbackstringGlobal function name called on success with the token.
data-error-callbackstringGlobal function name called on error.
data-themestring"light", "dark", or "auto" (default: auto-detect).

Drop-In Replacement

BenEgeDeniz Forge acts as a 100% native drop-in replacement for other popular captcha services. If your system already uses one of the services below, you can switch simply by changing the script URL, without modifying your HTML elements or server validation variables.

reCaptcha
<div class="g-recaptcha">
Turnstile
<div class="cf-turnstile">
hCaptcha
<div class="h-captcha">

Server-Side

After the widget generates a token, verify it on your server before processing the request.

PHP
$response = file_get_contents('https://forge.benegedeniz.com/api/siteverify', false,
    stream_context_create(['http' => [
        'method' => 'POST',
        'header' => 'Content-Type: application/json',
        'content' => json_encode([
            'secret' => 'YOUR_SECRET_KEY',
            'response' => $_POST['forge-captcha-response'],
            'remoteip' => $_SERVER['REMOTE_ADDR'],
        ]),
    ]])
);

$result = json_decode($response, true);
if ($result['success']) {
    // User verified - process the form
}
Node.js
const res = await fetch('https://forge.benegedeniz.com/api/siteverify', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
        secret: process.env.FORGE_SECRET_KEY,
        response: req.body['forge-captcha-response'],
    }),
});

const data = await res.json();
if (data.success) {
    // User verified
}
cURL
curl -X POST https://forge.benegedeniz.com/api/siteverify \
  -H "Content-Type: application/json" \
  -d '{"secret":"YOUR_SECRET","response":"TOKEN_FROM_WIDGET"}'

API Reference

POST /api/challenge

Request a new PoW challenge. Used internally by the widget.

Request Body
{ "sitekey": "your-site-uuid" }
Response
{
    "success": true,
    "challenge_id": "uuid",
    "salt": "hex-string",
    "difficulty": 20,
    "algorithm": "SHA-256",
    "expires_at": "2025-01-01T00:00:00Z"
}
POST /api/siteverify

Verify a captcha token. Call this from your server with your secret key.

Request Body
{
    "secret": "your-secret-key",
    "response": "token-from-widget",
    "remoteip": "optional-client-ip"
}
Response
{
    "success": true,
    "challenge_ts": "2025-01-01T00:00:00+00:00",
    "hostname": "example.com"
}

Configuration

Configure your site's difficulty level in the dashboard.

Setting Default Range Description
Difficulty 20 10–28 Number of leading zero bits required in the SHA-256 hash. Higher values = harder challenges.
Difficulty Guide
  • 10–14: Very light protection (~10ms). Good for low-risk forms.
  • 15–20: Balanced protection (~200-500ms). Recommended for most use cases.
  • 21–28: Heavy protection (~2-30s). For high-security or rate-limited endpoints.