Free, no registration required

Drop-in visual CAPTCHA widget

Add a resilient, image-based human check to any form. One script tag, one div, no user accounts.

1. HTML – add to your form

Insert this inside your form where you want the CAPTCHA. Everyone uses the same free public key. You can set data-width and data-height (default 260px × 60px). Use px or %, e.g. data-width="20%".

<div class="captchalink-widget"
     data-sitekey="pk_free_captchalink_demo"
     data-width="260px"
     data-height="60px"></div>

<script src="https://captchal.ink/captchalink.js"></script>
No registrations Single global key Token auto-injected

2. Backend (PHP) – verify token

The widget injects a hidden field captcha_token into your form. With method="POST" the token is sent in the request body (not in the URL). With method="GET" it appears in the URL. Prefer POST so the token is not visible in the address bar.

POST https://captchal.ink/api/verify.php
Content-Type: application/json

{
  "private_key": "sk_free_captchalink_demo_secret",
  "token": "token_from_captcha_token_field"
}

Response: {"success": true} or {"success": false, "error": "..."}. Only proceed when success === true.

Example 1 – file_get_contents

<?php
$token = $_POST["captcha_token"] ?? $_GET["captcha_token"] ?? "";
if ($token === "") {
    echo "Captcha FAIL";
    exit;
}

$url = "https://captchal.ink/api/verify.php";
$data = [
    "private_key" => "sk_free_captchalink_demo_secret",
    "token" => $token
];

$options = [
    "http" => [
        "header"  => "Content-Type: application/json\r\n",
        "method"  => "POST",
        "content" => json_encode($data)
    ]
];

$context = stream_context_create($options);
$result = @file_get_contents($url, false, $context);
$response = $result ? json_decode($result, true) : null;

if ($response && ($response["success"] ?? false) === true) {
    echo "Captcha OK";
} else {
    echo "Captcha FAIL";
}
?>

Example 2 – cURL

<?php
$token = $_POST["captcha_token"] ?? $_GET["captcha_token"] ?? "";
if ($token === "") {
    echo "Captcha FAIL";
    exit;
}

$ch = curl_init("https://captchal.ink/api/verify.php");
$data = json_encode([
    "private_key" => "sk_free_captchalink_demo_secret",
    "token" => $token
]);

curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$result = curl_exec($ch);
curl_close($ch);

$response = $result ? json_decode($result, true) : null;

if ($response && ($response["success"] ?? false) === true) {
    echo "Captcha OK";
} else {
    echo "Captcha FAIL";
}
?>

3. Redirection after completion (with form)

After the user completes the CAPTCHA and submits the form, your backend verifies the token. If verification succeeds, redirect them: header("Location: /welcome"); exit;

4. Redirect without form (no submit button)

If you want a flow like our short links: solve captcha → redirect immediately (no form, no submit button), use the widget alone and listen for the token in JavaScript:

<div class="captchalink-widget"
     data-sitekey="pk_free_captchalink_demo"
     data-width="260px"
     data-height="60px"></div>

<script src="https://captchal.ink/captchalink.js"></script>
<script>
window.addEventListener('message', function(e) {
    if (!e.data || e.data.type !== 'captchalink:succeeded' || !e.data.token) return;
    fetch('https://captchal.ink/api/verify.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            private_key: "sk_free_captchalink_demo_secret",
            token: e.data.token
        })
    })
    .then(function(r) { return r.json(); })
    .then(function(data) {
        if (data.success) {
            window.location.href = '/your-page';  // redirect after solve
        } else {
            alert('Verification failed.');
            location.reload();
        }
    });
});
</script>

Your backend endpoint should verify the token (see Example 1 or 2) and return {"success": true}. Or build a custom endpoint that verifies the token and returns the redirect URL in JSON, then use window.location.href = data.url;

Preview – your form with CAPTCHAL.ink

This preview does not submit anywhere – it just shows how the widget looks embedded.