SERVER VERIFICATION

Consume the response once, then enforce its context.

Use a short timeout, keep the secret outside source control, and fail the protected action when verification cannot be completed safely.

Maintained documentation4 sectionsAPI contract

PHP

Use a server-side HTTP client in production; this dependency-free example shows the required form fields and checks.

php
$payload = http_build_query([
    'secret' => getenv('GIWS_CAPTCHA_SECRET'),
    'response' => $_POST['giws-captcha-response'] ?? '',
    'sitekey' => getenv('GIWS_CAPTCHA_SITE_KEY'),
    'action' => 'login',
]);

$context = stream_context_create(['http' => [
    'method' => 'POST',
    'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
    'content' => $payload,
    'timeout' => 5,
]]);
$result = json_decode(file_get_contents('https://captcha.giws.us/api/siteverify', false, $context), true, flags: JSON_THROW_ON_ERROR);

if (! $result['success'] || $result['action'] !== 'login' || $result['hostname'] !== 'example.com' || $result['decision'] === 'block') {
    throw new RuntimeException('CAPTCHA verification failed.');
}

Laravel

Configure the endpoint and credentials from environment-backed service configuration.

php
$result = Http::asForm()->timeout(5)->post(config('services.giws.verify_url'), [
    'secret' => config('services.giws.secret'),
    'response' => $request->string('giws-captcha-response')->toString(),
    'sitekey' => config('services.giws.site_key'),
    'action' => 'login',
])->throw()->json();

abort_unless(
    $result['success']
    && $result['action'] === 'login'
    && $result['hostname'] === 'example.com'
    && $result['decision'] !== 'block',
    422,
    'CAPTCHA verification failed.'
);

Node.js

Node 18 and later provide fetch without an additional dependency.

javascript
const body = new URLSearchParams({
  secret: process.env.GIWS_CAPTCHA_SECRET,
  response: request.body['giws-captcha-response'],
  sitekey: process.env.GIWS_CAPTCHA_SITE_KEY,
  action: 'login',
});

const apiResponse = await fetch('https://captcha.giws.us/api/siteverify', {
  method: 'POST',
  body,
  signal: AbortSignal.timeout(5000),
});
const result = await apiResponse.json();

if (!result.success || result.action !== 'login' || result.hostname !== 'example.com' || result.decision === 'block') {
  throw new Error('CAPTCHA verification failed.');
}

Python

This standard-library example posts a form body and enforces the verified context.

python
import json
import os
import urllib.parse
import urllib.request

payload = urllib.parse.urlencode({
    "secret": os.environ["GIWS_CAPTCHA_SECRET"],
    "response": submitted_response,
    "sitekey": os.environ["GIWS_CAPTCHA_SITE_KEY"],
    "action": "login",
}).encode()

request = urllib.request.Request("https://captcha.giws.us/api/siteverify", data=payload)
with urllib.request.urlopen(request, timeout=5) as response:
    result = json.load(response)

if not result["success"] or result["action"] != "login" or result["hostname"] != "example.com" or result["decision"] == "block":
    raise RuntimeError("CAPTCHA verification failed.")