Skip to content

Callbacks (Webhooks)

Instead of polling getTaskResult repeatedly, you can provide a callback URL when creating a task. When the task completes, uCaptcha sends the result directly to your server.

  1. Include a callbackUrl in your createTask request.
  2. uCaptcha solves the task as usual.
  3. When the task completes (or fails), uCaptcha sends a GET request to your callback URL with the result as query parameters.

Include the callbackUrl field in your createTask request:

{
"clientKey": "YOUR_API_KEY",
"task": {
"type": "RecaptchaV2TaskProxyless",
"websiteURL": "https://example.com",
"websiteKey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
},
"callbackUrl": "https://your-server.com/captcha-callback"
}

Use the pingback parameter in your /in.php request:

GET https://api.ucaptcha.net/in.php?key=YOUR_API_KEY&method=userrecaptcha&googlekey=SITE_KEY&pageurl=https://example.com&pingback=https://your-server.com/captcha-callback

When the task completes, uCaptcha sends a GET request to your callback URL:

GET https://your-server.com/captcha-callback?captcha_id=TASK_ID&status=1&code=SOLUTION
ParameterDescription
captcha_idThe task ID (same as taskId from createTask)
status1 for success, 0 for failure
codeSolution token (only present when status is 1)
GET https://your-server.com/captcha-callback?captcha_id=550e8400-e29b-41d4-a716-446655440000&status=1&code=03AGdBq24PBCbwiDRkh3FOcMZ1Xi5sEKH...
GET https://your-server.com/captcha-callback?captcha_id=550e8400-e29b-41d4-a716-446655440000&status=0

Callback URLs are validated to prevent server-side request forgery (SSRF). The following address ranges are blocked:

  • localhost and 127.0.0.0/8 (loopback)
  • 10.0.0.0/8 (private)
  • 172.16.0.0/12 (private)
  • 192.168.0.0/16 (private)
  • 169.254.0.0/16 (link-local)
  • ::1 and fc00::/7 (IPv6 loopback and private)

Your callback URL must resolve to a publicly accessible IP address.

  • Callback requests have a 10-second timeout. If your server does not respond within 10 seconds, the request is abandoned.
  • Your server should return an HTTP 200 response as quickly as possible. Process the result asynchronously if needed.
from flask import Flask, request
app = Flask(__name__)
@app.route("/captcha-callback")
def captcha_callback():
task_id = request.args.get("captcha_id")
status = request.args.get("status")
solution = request.args.get("code")
if status == "1":
print(f"Task {task_id} solved: {solution}")
# Process the solution (e.g., submit a form, store in DB)
else:
print(f"Task {task_id} failed")
# Handle failure (e.g., retry, alert)
return "OK", 200
if __name__ == "__main__":
app.run(port=8080)
const express = require("express");
const app = express();
app.get("/captcha-callback", (req, res) => {
const { captcha_id, status, code } = req.query;
if (status === "1") {
console.log(`Task ${captcha_id} solved: ${code}`);
// Process the solution
} else {
console.log(`Task ${captcha_id} failed`);
// Handle failure
}
res.sendStatus(200);
});
app.listen(8080, () => console.log("Callback server running on port 8080"));