///
reCAPTCHA v2 API Integration: How to Connect and Use
CapMonster Cloud Team
CapMonster Cloud Team
Automation Experts
July 2, 2026
9 min
Please review the terms of use for the materials on this website.

reCAPTCHA v2 API Integration: How to Connect and Use

reCAPTCHA v2 API integration is a standard security task for web developers in 2026. Google's reCAPTCHA v2 works in two variants: the familiar "I'm not a robot" checkbox, and an invisible mode that triggers silently in the background. In both cases, the mechanism is the same — a client-side widget generates a one-time token, and your server verifies it against Google's siteverify API before processing the request.

This guide covers the full integration path: site registration, HTML widget embedding, server-side token verification, and common error handling. It also addresses the automation side — what to do when reCAPTCHA v2 appears in workflows that can't involve a human. For a broader overview, start with our reCAPTCHA v2 solver page.

 

Expert Take — Vladlen Vlasov, Development and Web Security Expert

"reCAPTCHA v2 integration details still matter in 2026 precisely because the widget is so widely deployed. Getting the server-side verification step wrong — or skipping it entirely — is still one of the most common security issues I see on developer forums. The client-side widget is only half the story."

 

robots
Get started now and automate your solution reCAPTCHA v2

What Is reCAPTCHA v2 and How Does It Work?

reCAPTCHA v2 is a CAPTCHA service from Google that distinguishes human users from automated bots. It works in two phases: a client-side phase where the browser renders the widget and generates a response token upon user interaction, and a server-side phase where your backend verifies that token with Google's API.

900ff128cf18f23d670e309c4d71bc51.png

The checkbox variant asks the user to click "I'm not a robot." Google's risk analysis engine runs in the background; if the score is borderline, an image challenge is presented. The invisible variant skips the visible checkbox and fires automatically on a configured action, usually form submission, showing a challenge only when the risk score demands it.

recaptcha.png

Understanding the difference between v2 and its siblings matters for integration decisions. See reCAPTCHA v2 vs v3 vs Enterprise: Key Differences for a detailed technical breakdown.


Prerequisites Before You Integrate reCAPTCHA v2

Before you start coding, you need two things from Google: a Site Key and a Secret Key.

Registering Your Site

  1. Go to google.com/recaptcha/admin/create and sign in with a Google account.
  2. Enter a label, select reCAPTCHA v2, and choose the checkbox or invisible variant.
  3. Add your domain under Domains. Add localhost if you're testing locally.
  4. Select an existing Google Cloud Platform project or create a new one. reCAPTCHA Classic was migrated to GCP in early 2026, so all keys are now scoped to a GCP project.
  5. Accept the Terms of Service and click Submit.
unnamed-8.png

Google will display two keys:

  • Site Key — public, embedded in your HTML.
  • Secret Key — private, used only on your server. Never expose it in client-side code.

google-recaptcha-site-secret-keys.jpg (1791×1040).png

You need HTTPS in production. reCAPTCHA can work over HTTP on localhost during development, but live deployments require a secure connection and outbound HTTPS access to www.google.com for verification.


Adding reCAPTCHA v2 to Your HTML Form

Loading the reCAPTCHA Script

Place the following script tag in the <head> of your page, or just before the closing </body> tag:

<script src="https://www.google.com/recaptcha/api.js" async defer></script>

The async defer attributes prevent the script from blocking page rendering.

Placing the Widget with data-sitekey

For the standard checkbox variant, add a div inside your form with the g-recaptcha class and your Site Key:

<form method="POST" action="/submit">
  *<!-- your form fields -->*
  <div class="g-recaptcha" data-sitekey="YOUR_SITE_KEY"></div>
  <button type="submit">Submit</button>
</form>

When the page loads, Google's script replaces this div with the interactive widget. On successful interaction, it populates a hidden input named g-recaptcha-response that is submitted with the form.

Invisible Variant Setup

The invisible variant attaches to your submit button rather than rendering a visible widget:

<form method="POST" action="/submit">
  *<!-- your form fields -->*
  <button
    class="g-recaptcha"
    data-sitekey="YOUR_SITE_KEY"
    data-callback="onSubmit"
    data-action="submit"
    type="submit">
    Submit
  </button>
</form>

<script>
  function onSubmit(token) {
    document.getElementById('your-form-id').submit();
  }
</script>

The data-callback function receives the token and triggers the actual form submission. Without this callback, the form will not submit after reCAPTCHA completes.

robots
Get started now and automate your solution reCAPTCHA v2

Server-Side Verification with the siteverify API

Embedding the widget is only the first half of a secure reCAPTCHA v2 integration. You must verify the token on your server. A token that is never verified provides no bot protection.

The flow is straightforward: the user interacts with the widget → Google returns a g-recaptcha-response token to the browser → the token is submitted to your server with the form → your server POSTs the token and your Secret Key to https://www.google.com/recaptcha/api/siteverify → Google responds with a JSON result.

POST Request to siteverify

The verification endpoint accepts a POST request with two required parameters:

ParameterDescription
secretYour Secret Key
responseThe g-recaptcha-response token from the client
remoteip (optional)The user's IP address

Parsing the JSON Response and Handling Errors

A successful verification returns:

{
  "success": true,
  "challenge_ts": "2026-06-17T10:00:00Z",
  "hostname": "yourdomain.com",
  "error-codes": []
}

A failed verification returns "success": false and one or more error codes:

Error CodeMeaning
missing-input-secretSecret Key parameter not sent
invalid-input-secretSecret Key is incorrect or malformed
missing-input-responseToken not submitted by the client
invalid-input-responseToken is invalid or malformed
timeout-or-duplicateToken expired or already used

Always check success === true before proceeding. Do not rely on the absence of error codes alone.

PHP Server-Side Verification Example

The following example shows complete server-side verification functions. Replace $YOUR_SECRET_KEY with your actual Secret Key.

<?php
declare(strict_types=1);
function verifyRecaptchaV2(
    string $token,
    string $YOUR_SECRET_KEY,
    ?string $remoteIp = null
): array {
    if ($token === "") {
        return [
            "ok" => false,
            "message" => "reCAPTCHA token was not received.",
            "data" => null,
        ];
    }
    $postFields = [
        "secret" => $YOUR_SECRET_KEY,
        "response" => $token,
    ];
    if ($remoteIp !== null && $remoteIp !== "") {
        $postFields["remoteip"] = $remoteIp;
    }
    $ch = curl_init("https://www.google.com/recaptcha/api/siteverify");
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query($postFields),
        CURLOPT_TIMEOUT => 10,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
    ]);
    $responseBody = curl_exec($ch);
    $curlError = curl_error($ch);
    $httpCode = (int) curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    curl_close($ch);
    if ($responseBody === false || $curlError !== "") {
        return [
            "ok" => false,
            "message" => "Failed to send a request to Google reCAPTCHA.",
            "data" => null,
        ];
    }
    if ($httpCode < 200 || $httpCode >= 300) {
        return [
            "ok" => false,
            "message" => "Google reCAPTCHA returned an unexpected HTTP status.",
            "data" => null,
        ];
    }
    $data = json_decode($responseBody, true);
    if (!is_array($data)) {
        return [
            "ok" => false,
            "message" => "Failed to parse the Google reCAPTCHA response.",
            "data" => null,
        ];
    }
    if (!empty($data["success"])) {
        return [
            "ok" => true,
            "message" => "reCAPTCHA verification passed successfully.",
            "data" => $data,
        ];
    }
    $errors =
        isset($data["error-codes"]) && is_array($data["error-codes"])
            ? implode(", ", $data["error-codes"])
            : "unknown_error";
    return [
        "ok" => false,
        "message" => "reCAPTCHA verification failed: " . $errors,
        "data" => $data,
    ];
}

Using reCAPTCHA v2 in JavaScript

After integrating reCAPTCHA v2, you can interact with the widget directly through the JavaScript API. The table below covers the key methods and callbacks.

Method / CallbackPurpose
grecaptcha.render()Render the widget manually into a container element
grecaptcha.getResponse()Get the current response token (empty string if not yet solved)
grecaptcha.reset()Reset the current challenge so the user can solve it again
callbackFires when the user successfully completes the challenge; receives the token
expired-callbackFires when a solved token expires before submission

Practical JavaScript Examples

Get the generated token:

const token = grecaptcha.getResponse();

Reset the widget after a failed request:

grecaptcha.reset();

Render the widget dynamically (useful in SPAs or when the container is injected after page load):

function onSolved(token) {
  document.querySelector('textarea[name="g-recaptcha-response"]').value = token;
  document.getElementById('contact-form').submit();
}
grecaptcha.render('captcha-container', {
  sitekey: 'YOUR_SITE_KEY',
  callback: onSolved,
  'expired-callback': () => grecaptcha.reset(),
});

Check whether the user has completed the challenge before submitting:

if (!grecaptcha.getResponse()) {
  alert('Complete the CAPTCHA first.');
  return;
}

The expired-callback is easy to miss: if the user solves the challenge but waits more than two minutes before submitting, the token silently expires. Without this handler, your form will submit an invalid token and fail server-side verification with timeout-or-duplicate.


Common Integration Errors and How to Fix Them

Even a straightforward reCAPTCHA v2 integration can break in predictable ways.

ProblemLikely CauseFix
Widget does not renderScript tag missing or blocked by CSPAdd https://www.google.com to your CSP script-src and frame-src
invalid-input-secret on verifySecret Key is wrong or from the wrong projectCheck the Admin Console and confirm you're using the correct Secret Key
timeout-or-duplicateToken older than \~2 minutes, or submitted twiceRe-prompt the user and never reuse a token
invalid-input-responseToken not forwarded to serverLog req.body['g-recaptcha-response'] to confirm it reaches your handler
Domain mismatch error in consoleDomain not registered in Admin ConsoleAdd the exact domain in the reCAPTCHA Admin settings
Widget breaks on SPA route changeWidget not re-rendered after DOM manipulationCall grecaptcha.render() or reset with grecaptcha.reset()
missing-input-response on AJAX formsToken field not included in AJAX payloadRead grecaptcha.getResponse() and append it to your fetch or XHR body

Never treat a missing token as a passed check. If g-recaptcha-response is absent, reject the request immediately.


reCAPTCHA v2 for Automation: The Solver API Approach

You’ve just added reCAPTCHA v2 to your site — now it’s time to test how it behaves in practice. Instead of solving the challenge manually on every check, you can send your reCAPTCHA’s public parameters to CapMonster Cloud, receive a valid token, and use it to test different scenarios in your integration.

The CapMonster Cloud reCAPTCHA v2 solving API follows a four-step pattern:

  1. Submit a task with the target page URL and sitekey.
  2. Poll for the result.
  3. Insert the returned token into g-recaptcha-response.
  4. Submit the form before the token expires.

CapMonster Cloud offers a reCAPTCHA v2 solver API that follows this token-return pattern.

For a practical walkthrough, see How to Solve reCAPTCHA v2 in 2026: Working Methods. If you're comparing vendors, Best reCAPTCHA v2 Solving Services in 2026 gives a structured overview.

 

Key Insight — Vladlen Vlasov, Development and Web Security Expert

"The developer adding reCAPTCHA to a site and the automation engineer encountering it in a pipeline are solving mirror-image problems. Understanding both sides makes you better at each: a tighter server-side integration is harder to bypass, and a well-structured solver API integration is more reliable when tokens expire or pages change."

 

robots
Get started now and automate your solution reCAPTCHA v2

FAQ

The most common causes are token expiry and domain mismatch. Tokens are valid for about two minutes, so delays before verification can cause a failure. Domain mismatch happens when the domain registered in the Admin Console does not match the domain where the widget is loaded.

The Site Key is public and belongs in your HTML. The Secret Key is private and belongs only on your server when you call `siteverify`. If the Secret Key is exposed in client-side code or a public repository, your verification flow is compromised.

Yes, but you need explicit widget management. In SPAs, route changes do not automatically re-trigger widget rendering, so use `grecaptcha.render()` when a view mounts and 'grecaptcha.reset()' after a failed submission.

After the user completes the challenge, read the token with 'grecaptcha.getResponse()' and include it in your fetch or XHR body. On the server, verify it exactly as you would in a normal form POST.

Conclusion

A correct reCAPTCHA v2 API integration requires two parts: a working client-side widget and a server-side siteverify check that actually gates request handling. For most projects, the checkbox variant is the safest starting point — easier to implement, simpler to debug, and clearer for users. The invisible variant makes sense when reducing friction is a measurable priority and your callback flow is solid. If your automation workflows need to handle reCAPTCHA v2 programmatically, the token-injection model is straightforward — the main constraint is token lifetime, so fetch and submit quickly.


Get reCAPTCHA v2 Tokens for Your Automation Pipelines

If your automation workflows encounter reCAPTCHA v2 at scale, manual solving does not hold up. CapMonster Cloud provides a reCAPTCHA v2 solver API that fits the same integration pattern described in this guide — send the sitekey and page URL, receive a ready-to-use token.

  • Compatible with browser automation and direct HTTP workflows
  • Simple API pattern for task creation and result retrieval
  • Built for reCAPTCHA-related automation use cases

Explore the supported reCAPTCHA v2 workflow on the reCAPTCHA v2 overview page.


NB: Please note that the product is intended for automating tests on your own websites and sites you have legal access to.
ItGuy
geear
Affiliate program for software developers
Earn up to 30% from your users’ spending on captcha bypass
✅ Request sent
Thank you for your interest in our partnership program! We will contact you within 7 working days.
Request to Join
Fill out the form to submit an application for the affiliate program.
More articles