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).

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.