API Tutorials

How to Solve reCAPTCHA v3 Enterprise with PHP

reCAPTCHA v3 Enterprise runs silently in the background and assigns a risk score to every interaction. Unlike standard v3, it uses Google's Enterprise backend with enhanced ML models and reason codes. To solve it with CaptchaAI in PHP, add version=v3 and enterprise=1 to your request.

This guide covers the full PHP implementation — from identifying Enterprise v3 on a page to injecting the solved token.


What you need

Requirement Details
CaptchaAI API key captchaai.com
PHP 7.4+ With curl extension enabled
Sitekey From enterprise.js?render=SITEKEY
Action From grecaptcha.enterprise.execute(key, {action: '...'})
Page URL Full URL where v3 Enterprise runs

Step 1: Identify reCAPTCHA v3 Enterprise

Check the page source for Enterprise v3 indicators:

<!-- Enterprise v3 script -->
<script src="https://www.google.com/recaptcha/enterprise.js?render=6LdxxXXx..."></script>

<!-- Enterprise v3 execute call -->
<script>
  grecaptcha.enterprise.execute('6LdxxXXx...', {action: 'login'}).then(function(token) {
    document.getElementById('g-recaptcha-response').value = token;
  });
</script>

Key differences from standard v3:

  • Script loads from enterprise.js (not api.js)
  • JS call uses grecaptcha.enterprise.execute() (not grecaptcha.execute())
  • No visible challenge — it runs silently

Step 2: Submit the task to CaptchaAI

<?php

$apiKey = "YOUR_API_KEY";
$siteKey = "6LdxxXXxAAAAAAcXxxXxxX91xxxxxxxx8xxOx7A";
$pageUrl = "https://example.com/login";
$action = "login";

// Submit task
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://ocr.captchaai.com/in.php");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
    'key'        => $apiKey,
    'method'     => 'userrecaptcha',
    'version'    => 'v3',
    'enterprise' => 1,
    'googlekey'  => $siteKey,
    'pageurl'    => $pageUrl,
    'action'     => $action,
    'json'       => 1
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

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

$data = json_decode($response, true);

if ($data['status'] !== 1) {
    die("Submit failed: " . $data['request']);
}

$taskId = $data['request'];
echo "Task submitted. ID: {$taskId}\n";

Step 3: Poll for the result

Wait 20 seconds, then poll every 5 seconds:

// Poll for result
sleep(20);

for ($i = 0; $i < 30; $i++) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://ocr.captchaai.com/res.php?" . http_build_query([
        'key'    => $apiKey,
        'action' => 'get',
        'id'     => $taskId,
        'json'   => 1
    ]));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

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

    $result = json_decode($response, true);

    if ($result['status'] === 1) {
        $token = $result['request'];
        $userAgent = $result['user_agent'] ?? '';
        echo "Solved. Token: " . substr($token, 0, 60) . "...\n";
        if ($userAgent) {
            echo "User-Agent: {$userAgent}\n";
        }
        break;
    }

    if ($result['request'] !== 'CAPCHA_NOT_READY') {
        die("Solve failed: " . $result['request']);
    }

    echo "Attempt " . ($i + 1) . ": not ready, waiting 5s...\n";
    sleep(5);
}

Step 4: Inject the token

Submit the solved token as g-recaptcha-response with the solver's User-Agent:

// Submit token to target site
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://example.com/api/login");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
    'username'             => 'user',
    'password'             => 'pass',
    'g-recaptcha-response' => $token
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

if ($userAgent) {
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        "User-Agent: {$userAgent}"
    ]);
}

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

echo "Response status: {$httpCode}\n";

Complete working script

<?php

$apiKey   = "YOUR_API_KEY";
$siteKey  = "6LdxxXXxAAAAAAcXxxXxxX91xxxxxxxx8xxOx7A";
$pageUrl  = "https://example.com/login";
$action   = "login";

function solveRecaptchaV3Enterprise($apiKey, $siteKey, $pageUrl, $action) {
    // Submit task
    $ch = curl_init("https://ocr.captchaai.com/in.php");
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POSTFIELDS     => [
            'key'        => $apiKey,
            'method'     => 'userrecaptcha',
            'version'    => 'v3',
            'enterprise' => 1,
            'googlekey'  => $siteKey,
            'pageurl'    => $pageUrl,
            'action'     => $action,
            'json'       => 1
        ]
    ]);
    $data = json_decode(curl_exec($ch), true);
    curl_close($ch);

    if ($data['status'] !== 1) {
        throw new Exception("Submit error: " . $data['request']);
    }

    $taskId = $data['request'];
    echo "Task ID: {$taskId}\n";

    // Poll for result
    sleep(20);
    for ($i = 0; $i < 30; $i++) {
        $ch = curl_init("https://ocr.captchaai.com/res.php?" . http_build_query([
            'key' => $apiKey, 'action' => 'get', 'id' => $taskId, 'json' => 1
        ]));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $result = json_decode(curl_exec($ch), true);
        curl_close($ch);

        if ($result['status'] === 1) {
            return [
                'token'      => $result['request'],
                'user_agent' => $result['user_agent'] ?? ''
            ];
        }
        if ($result['request'] !== 'CAPCHA_NOT_READY') {
            throw new Exception("Solve error: " . $result['request']);
        }
        sleep(5);
    }

    throw new Exception("Solve timed out");
}

$solution = solveRecaptchaV3Enterprise($apiKey, $siteKey, $pageUrl, $action);
echo "Token: " . substr($solution['token'], 0, 60) . "...\n";
if ($solution['user_agent']) {
    echo "User-Agent: " . $solution['user_agent'] . "\n";
}

Expected output:

Task ID: 73849562810
Token: 03AGdBq24PBCqLmOx2V4pGHJjkR2xZ1r...
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)...

Troubleshooting

Error Cause Fix
ERROR_WRONG_USER_KEY Invalid API key format Check key is 32 characters
ERROR_ZERO_BALANCE Insufficient balance Top up your account
ERROR_BAD_TOKEN_OR_PAGEURL Wrong sitekey or URL Extract correct sitekey from enterprise.js?render=
ERROR_CAPTCHA_UNSOLVABLE Could not solve Verify it is Enterprise v3 (not standard v3)
Token rejected Wrong action value Use the exact action from grecaptcha.enterprise.execute()
Token rejected User-Agent mismatch Use the user_agent from the solve response

FAQ

What PHP version and extensions do I need?

PHP 7.4+ with the curl extension. Most PHP installations include curl by default.

What score does CaptchaAI return for Enterprise v3?

Typically around 0.3. Most sites accept this score, but sites with higher thresholds may require retries.

How do I find the action value?

Search the page source for grecaptcha.enterprise.execute. The second argument contains {action: 'value'}.

What is the difference between Enterprise v3 and standard v3?

Enterprise v3 uses enterprise.js and grecaptcha.enterprise.execute(). For CaptchaAI, add enterprise=1 alongside version=v3. Standard v3 only needs version=v3.

Can I set min_score in my request?

Yes. Add min_score=0.7 to request a higher target score, though scores above 0.7 are significantly rarer.


Start solving reCAPTCHA v3 Enterprise

Get your API key at captchaai.com. Add version=v3 and enterprise=1 to your request.


Full Working Code

Complete runnable examples for this article in Python, Node.js, PHP, Go, Java, C#, Ruby, Rust, Kotlin & Bash.

View on GitHub →

Discussions (0)

No comments yet.