Instead of polling /res.php repeatedly, you can provide a callback URL. CaptchaAI sends the solved token directly to your server when ready. This eliminates polling overhead and reduces latency.
How Callbacks Work
Standard polling approach:
Submit ──▶ Wait ──▶ Poll ──▶ Poll ──▶ Poll ──▶ Result
(many requests, wasted time between polls)
Callback approach:
Submit (with callback URL) ──▶ ... CaptchaAI solves ...
│
Your server receives POST ◀───────────────┘
(one request, instant delivery)
Submit with Callback URL
Add the pingback parameter to your submit request:
import requests
API_KEY = "YOUR_API_KEY"
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": "SITE_KEY",
"pageurl": "https://example.com",
"pingback": "https://your-server.com/captcha-callback",
"json": 1,
})
result = resp.json()
task_id = result["request"]
print(f"Task submitted: {task_id}")
# No polling needed — result comes via webhook
Supported for All CAPTCHA Types
# reCAPTCHA v2
data = {
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": "SITE_KEY",
"pageurl": "https://example.com",
"pingback": "https://your-server.com/callback",
"json": 1,
}
# Turnstile
data = {
"key": API_KEY,
"method": "turnstile",
"sitekey": "SITE_KEY",
"pageurl": "https://example.com",
"pingback": "https://your-server.com/callback",
"json": 1,
}
# Image CAPTCHA
data = {
"key": API_KEY,
"method": "base64",
"body": base64_image,
"pingback": "https://your-server.com/callback",
"json": 1,
}
Build a Callback Receiver (Flask)
from flask import Flask, request
import threading
import logging
app = Flask(__name__)
logger = logging.getLogger(__name__)
# Store results by task ID
results = {}
events = {}
@app.route("/captcha-callback", methods=["POST", "GET"])
def captcha_callback():
"""Receive solved CAPTCHA tokens from CaptchaAI."""
# CaptchaAI sends parameters as query string or form data
task_id = request.args.get("id") or request.form.get("id")
code = request.args.get("code") or request.form.get("code")
if not task_id or not code:
logger.warning("Callback missing id or code")
return "ERROR", 400
logger.info("Received result for task %s", task_id)
results[task_id] = code
# Notify waiting threads
event = events.get(task_id)
if event:
event.set()
return "OK"
def wait_for_result(task_id, timeout=120):
"""Wait for a callback result."""
event = threading.Event()
events[task_id] = event
if task_id in results:
return results.pop(task_id)
event.wait(timeout=timeout)
if task_id in results:
return results.pop(task_id)
raise TimeoutError(f"No callback received for task {task_id}")
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
Complete Workflow
import requests
import threading
import time
API_KEY = "YOUR_API_KEY"
CALLBACK_URL = "https://your-server.com/captcha-callback"
def solve_with_callback(sitekey, pageurl):
"""Submit CAPTCHA and wait for callback."""
# Submit with callback URL
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"pingback": CALLBACK_URL,
"json": 1,
})
result = resp.json()
if result.get("status") != 1:
raise RuntimeError(f"Submit failed: {result.get('request')}")
task_id = result["request"]
print(f"Task {task_id} submitted, waiting for callback...")
# Wait for callback on the receiver
token = wait_for_result(task_id, timeout=120)
print(f"Token received via callback: {token[:50]}...")
return token
Callback vs Polling Comparison
| Factor | Polling | Callback |
|---|---|---|
| API requests | Many (submit + N polls) | 2 (submit + callback) |
| Latency | Poll interval delay | Instant delivery |
| Server load | Client polls continuously | CaptchaAI pushes result |
| Complexity | Simple (client-only) | Requires public endpoint |
| Firewall requirements | Outbound only | Must accept inbound POST |
| Best for | Simple scripts | Production pipelines |
When to Use Callbacks
| Scenario | Recommended Approach |
|---|---|
| Quick script, few solves | Polling |
| Production pipeline, high volume | Callback |
| Serverless (Lambda, Cloud Functions) | Polling (no persistent server) |
| Behind firewall, no public IP | Polling |
| Microservice architecture | Callback |
Securing Your Callback Endpoint
Verify that callbacks actually come from CaptchaAI:
from flask import Flask, request, abort
app = Flask(__name__)
# Store submitted task IDs to validate callbacks
pending_tasks = set()
def submit_captcha(sitekey, pageurl):
"""Submit and track task ID."""
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": sitekey,
"pageurl": pageurl,
"pingback": CALLBACK_URL,
"json": 1,
})
task_id = resp.json()["request"]
pending_tasks.add(task_id)
return task_id
@app.route("/captcha-callback", methods=["POST", "GET"])
def secure_callback():
"""Validate callback before processing."""
task_id = request.args.get("id") or request.form.get("id")
# Reject unknown task IDs
if task_id not in pending_tasks:
abort(403)
code = request.args.get("code") or request.form.get("code")
pending_tasks.discard(task_id)
results[task_id] = code
return "OK"
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
| No callback received | Server not publicly accessible | Use ngrok for testing, or deploy to cloud |
| Callback URL rejected | URL not reachable from CaptchaAI | Verify URL is publicly accessible |
| Partial results | Some callbacks fail | Log all callbacks, add retry/polling fallback |
| Duplicate callbacks | Network retry | Use task ID deduplication |
FAQ
Does the callback URL need HTTPS?
HTTPS is recommended for production. HTTP works for testing but exposes tokens in transit.
What if my callback server is down?
CaptchaAI may retry the callback, but you should implement a polling fallback for reliability. Check results via /res.php if no callback is received within the expected time.
Can I use different callback URLs per request?
Yes. Each pingback parameter is per-request. Different CAPTCHA types or projects can use different callback endpoints.
Related Guides
Eliminate polling overhead — try CaptchaAI callbacks for instant token delivery.
Discussions (0)
Join the conversation
Sign in to share your opinion.
Sign InNo comments yet.