PHP powers the majority of the web. This guide shows you how to integrate CaptchaAI into any PHP project using cURL — no SDKs or frameworks required.
Requirements
| Requirement | Details |
|---|---|
| PHP | 7.4+ |
| cURL extension | Enabled (default in most installs) |
| CaptchaAI API key | Get one here |
Helper Functions
Create a reusable solver class:
<?php
class CaptchaAI
{
private string $apiKey;
private string $baseUrl = 'https://ocr.captchaai.com';
public function __construct(string $apiKey)
{
$this->apiKey = $apiKey;
}
/**
* Submit a CAPTCHA task and return the task ID.
*/
public function submit(array $params): string
{
$params['key'] = $this->apiKey;
$url = $this->baseUrl . '/in.php?' . http_build_query($params);
$response = $this->httpGet($url);
if (!str_starts_with($response, 'OK|')) {
throw new RuntimeException("Submit failed: {$response}");
}
return explode('|', $response)[1];
}
/**
* Poll for the result with a timeout.
*/
public function poll(string $taskId, int $timeout = 300): string
{
$deadline = time() + $timeout;
$url = $this->baseUrl . '/res.php?' . http_build_query([
'key' => $this->apiKey,
'action' => 'get',
'id' => $taskId,
]);
while (time() < $deadline) {
sleep(5);
$response = $this->httpGet($url);
if ($response === 'CAPCHA_NOT_READY') {
continue;
}
if (str_starts_with($response, 'OK|')) {
return explode('|', $response, 2)[1];
}
throw new RuntimeException("Solve failed: {$response}");
}
throw new RuntimeException("Timeout after {$timeout}s for task {$taskId}");
}
/**
* Submit and poll in one call.
*/
public function solve(array $params, int $timeout = 300): string
{
$taskId = $this->submit($params);
return $this->poll($taskId, $timeout);
}
/**
* Check account balance.
*/
public function getBalance(): float
{
$url = $this->baseUrl . '/res.php?' . http_build_query([
'key' => $this->apiKey,
'action' => 'getbalance',
]);
return (float) $this->httpGet($url);
}
private function httpGet(string $url): string
{
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => true,
]);
$response = curl_exec($ch);
if ($response === false) {
$error = curl_error($ch);
curl_close($ch);
throw new RuntimeException("HTTP request failed: {$error}");
}
curl_close($ch);
return $response;
}
}
Solve reCAPTCHA v2
$solver = new CaptchaAI('YOUR_API_KEY');
$token = $solver->solve([
'method' => 'userrecaptcha',
'googlekey' => '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
'pageurl' => 'https://example.com/login',
]);
echo "Token: {$token}\n";
Solve reCAPTCHA v3
$token = $solver->solve([
'method' => 'userrecaptcha',
'googlekey' => '6Le-wvkS...',
'pageurl' => 'https://example.com',
'version' => 'v3',
'action' => 'submit',
]);
Solve Cloudflare Turnstile
$token = $solver->solve([
'method' => 'turnstile',
'sitekey' => '0x4AAAAA...',
'pageurl' => 'https://example.com',
]);
Solve Image CAPTCHAs
$imageData = base64_encode(file_get_contents('captcha.png'));
$text = $solver->solve([
'method' => 'base64',
'body' => $imageData,
]);
echo "Text: {$text}\n";
Solve GeeTest v3
$result = $solver->solve([
'method' => 'geetest',
'gt' => '022c...',
'challenge' => 'abc...',
'api_server' => 'api.geetest.com',
'pageurl' => 'https://example.com',
]);
// Parse GeeTest result
$parts = [];
foreach (explode(',', $result) as $item) {
[$key, $value] = explode(':', $item, 2);
$parts[$key] = $value;
}
echo "Challenge: {$parts['challenge']}\n";
echo "Validate: {$parts['validate']}\n";
echo "Seccode: {$parts['seccode']}\n";
Laravel Integration
Use the solver in a Laravel controller:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class FormController extends Controller
{
public function submit(Request $request)
{
$solver = new \CaptchaAI(config('services.captchaai.key'));
$token = $solver->solve([
'method' => 'userrecaptcha',
'googlekey' => config('services.captchaai.sitekey'),
'pageurl' => $request->url(),
]);
// Use token in form submission
$response = \Http::asForm()->post('https://target.com/submit', [
'g-recaptcha-response' => $token,
'other_field' => $request->input('data'),
]);
return response()->json(['success' => true]);
}
}
Add your key to config/services.php:
'captchaai' => [
'key' => env('CAPTCHAAI_API_KEY'),
],
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
cURL error: SSL certificate problem |
Outdated CA bundle | Update php.ini curl.cainfo path |
Submit failed: ERROR_WRONG_USER_KEY |
Invalid API key | Verify key from dashboard |
Timeout after 300s |
Network or capacity issue | Increase timeout; retry |
cURL error: Could not resolve host |
DNS issue | Check network connectivity |
FAQ
Does this work with PHP 8+?
Yes. The code uses str_starts_with() which requires PHP 8.0+. For PHP 7.4, replace with substr($str, 0, 3) === 'OK|'.
Can I use Guzzle instead of cURL?
Yes. Replace the httpGet method with a Guzzle client call. The API parameters stay the same.
How do I handle concurrent solves in PHP?
Use curl_multi_exec for parallel HTTP requests, or process CAPTCHAs in a queue (Laravel Queue, Symfony Messenger).
Discussions (0)
Join the conversation
Sign in to share your opinion.
Sign InNo comments yet.