Verify user response tokens with legacy SiteVerify

This page explains how to verify a user's response to a reCAPTCHA challenge from your application's backend using the legacy SiteVerify API endpoint (https://www.google.com/recaptcha/api/siteverify). Use this endpoint only if you're maintaining a legacy integration or third-party plugin that can't use CreateAssessment.

Before you begin

To call the SiteVerify endpoint, you need your key's legacy secret key. To find the secret key in the Google Cloud console, see Retrieve the secret key in the Google Cloud console. Keep your secret key safe on your backend server and never expose it in client-side code.

Retrieve the user's response token

Legacy web integrations load the non-enterprise JavaScript API (https://www.google.com/recaptcha/api.js), which provides methods on the grecaptcha object instead of grecaptcha.enterprise. You can retrieve the user's response token on your frontend in one of the following ways:

  • From the g-recaptcha-response POST parameter when the user submits a form on your site.
  • By calling grecaptcha.getResponse(opt_widget_id) after the user completes a reCAPTCHA v2 challenge. This method returns the response token as a string, or an empty string if the challenge isn't completed. The optional opt_widget_id parameter specifies the widget ID returned by grecaptcha.render(); if omitted, it defaults to the first widget created.
  • As a string argument passed to your callback function when the user completes a challenge, if you specify the callback function name in either the data-callback attribute of the g-recaptcha HTML element or the callback parameter of the grecaptcha.render(container, parameters) method.
  • From the resolved value of the Promise returned by grecaptcha.execute(site_key, {action: action_name}) for score-based (v3) keys.

The legacy grecaptcha methods (render, getResponse, execute, ready, and reset) and g-recaptcha tag attributes use the same parameters as the grecaptcha.enterprise equivalents. For parameter details, see the JavaScript API reference for reCAPTCHA.

To migrate to the updated reCAPTCHA JavaScript API, see Migrate the reCAPTCHA JavaScript API.

Token restrictions

Each reCAPTCHA user response token is valid for two minutes, and you can verify each token only once to prevent replay attacks. Verify the response token with reCAPTCHA within two minutes of receiving it. If you need a new token, run the reCAPTCHA verification again.

API request

Send a request with the following endpoint and method:

  • URL: https://www.google.com/recaptcha/api/siteverify (or https://www.recaptcha.net/recaptcha/api/siteverify if www.google.com isn't accessible; see Use reCAPTCHA globally)
  • Method: POST

Include the following POST parameters in the request:

POST parameter Description
secret Required. The shared secret key between your site and reCAPTCHA.
response Required. The user response token provided by the reCAPTCHA client-side integration on your site.
remoteip Optional. The user's IP address.

API response

The SiteVerify endpoint returns a JSON object.

For web integrations (score-based v3, checkbox v2, or invisible v2 keys), the response has the following format:

{
  "success": true|false,      // whether this request was a valid reCAPTCHA token for your site
  "score": number,            // the score for this request (0.0 - 1.0) for score-based (v3) keys
  "action": string,           // the action name for this request (important to verify)
  "challenge_ts": timestamp,  // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
  "hostname": string,         // the hostname of the site where the reCAPTCHA was solved
  "error-codes": [...]        // optional
}

Error code reference

The following table describes the error codes that can appear in the error-codes array:

Error code Description
missing-input-secret The secret parameter is missing.
invalid-input-secret The secret parameter is invalid or malformed.
missing-input-response The response parameter is missing.
invalid-input-response The response parameter is invalid or malformed.
bad-request The request is invalid or malformed.
timeout-or-duplicate The response is no longer valid because it expired or was already used.

What's next