API Documentation
Asynchronous API for solving captchas, compatible with the anti-captcha createTask / getTaskResult format. Create a task, poll for the result, pay only for solved captchas.
Authentication
Authentication uses your API key, passed as "clientKey" in the JSON body of every request. There is no separate auth header. You can find your key in the dashboard. All endpoints are POST and accept a JSON body.
Base URLHow it works
The API is asynchronous. Create a task and receive a taskId, then poll getTaskResult until the status is "ready". The recommended polling interval is once every 5 seconds. A task lives for 5 minutes; after that it expires and reserved funds are refunded.
Methods
The API has three POST methods: createTask submits a captcha, getTaskResult returns the solution, getBalance shows the account balance. Every request is a JSON body with clientKey.
POST /createTask
Creates a captcha-solving task and returns its taskId. The price of the task type is reserved on your balance and charged only if the task is solved.
Request{
"clientKey": "YOUR_API_KEY",
"task": {
"type": "RecaptchaV2TaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
Response
{
"errorId": 0,
"taskId": 100
}
Supported task types: v1 supports token captchas, proxyless or with your own proxy:
RecaptchaV2TaskProxyless // reCAPTCHA v2
RecaptchaV3TaskProxyless // reCAPTCHA v3 (websiteKey + minScore, pageAction)
TurnstileTaskProxyless // Cloudflare Turnstile
RecaptchaV2Task // reCAPTCHA v2 (your proxy)
TurnstileTask // Cloudflare Turnstile (your proxy)
Types without the Proxyless suffix are solved through your proxy and require proxyType (http, socks4 or socks5), proxyAddress and proxyPort. Optional: proxyLogin and proxyPassword (for proxies with authentication) and userAgent.
reCAPTCHA v2
Types RecaptchaV2TaskProxyless and RecaptchaV2Task. Optional field: isInvisible (true for invisible reCAPTCHA). The solution key is gRecaptchaResponse.
Task object examples// RecaptchaV2TaskProxyless
{
"type": "RecaptchaV2TaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"isInvisible": false
}
// RecaptchaV2Task (your proxy)
{
"type": "RecaptchaV2Task",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"proxyType": "http",
"proxyAddress": "1.2.3.4",
"proxyPort": 8080,
"proxyLogin": "user",
"proxyPassword": "password",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ..."
}
reCAPTCHA v3
Type RecaptchaV3TaskProxyless. Required field: minScore (minimum acceptable score, e.g. 0.3); optional: pageAction. No proxy is needed for v3: tasks are solved from the service IPs. The solution key is gRecaptchaResponse.
Task object examples// RecaptchaV3TaskProxyless
{
"type": "RecaptchaV3TaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"minScore": 0.3,
"pageAction": "login"
}
Cloudflare Turnstile
Types TurnstileTaskProxyless and TurnstileTask. No extra fields. The solution key is token.
Task object examples// TurnstileTaskProxyless
{
"type": "TurnstileTaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "0x4AAAAAAAxxxxxxxxxxxxxxxx"
}
// TurnstileTask (your proxy)
{
"type": "TurnstileTask",
"websiteURL": "https://example.com/login",
"websiteKey": "0x4AAAAAAAxxxxxxxxxxxxxxxx",
"proxyType": "http",
"proxyAddress": "1.2.3.4",
"proxyPort": 8080
}
POST /getTaskResult
Returns the task status. While solving, status is "processing"; when done, status is "ready" and "solution" holds the token. If the captcha could not be solved, an error is returned and the reserved funds are refunded.
Request{
"clientKey": "YOUR_API_KEY",
"taskId": 100
}
Response
{ "errorId": 0, "status": "processing" }
// reCAPTCHA v2 / v3
{
"errorId": 0,
"status": "ready",
"solution": { "gRecaptchaResponse": "03AGdBq..." }
}
// Turnstile
{
"errorId": 0,
"status": "ready",
"solution": { "token": "0.zxcv..." }
}
The solution key depends on the captcha type: gRecaptchaResponse for reCAPTCHA v2/v3, token for Turnstile.
POST /getBalance
Returns the current available balance of your account.
Request{ "clientKey": "YOUR_API_KEY" }
Response
{ "errorId": 0, "balance": 12.34 }
Code examples
A full cycle: create a task, then poll for the result. Replace YOUR_API_KEY, the website URL and the site key with your own values.
reCAPTCHA v2
# 1. Create a task
curl -s -X POST https://api.captcha-solver.com/createTask \
-H "Content-Type: application/json" \
-d '{
"clientKey": "YOUR_API_KEY",
"task": {
"type": "RecaptchaV2TaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}'
# -> {"errorId":0,"taskId":100}
# 2. Poll for the result (repeat every ~5s until status is "ready")
curl -s -X POST https://api.captcha-solver.com/getTaskResult \
-H "Content-Type: application/json" \
-d '{"clientKey":"YOUR_API_KEY","taskId":100}'
# -> {"errorId":0,"status":"processing"}
# -> {"errorId":0,"status":"ready","solution":{"gRecaptchaResponse":"03AGdBq..."}}
import time
import requests
BASE = "https://api.captcha-solver.com"
API_KEY = "YOUR_API_KEY"
# 1. Create a task
resp = requests.post(f"{BASE}/createTask", json={
"clientKey": API_KEY,
"task": {
"type": "RecaptchaV2TaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
},
}).json()
if resp["errorId"] != 0:
raise RuntimeError(resp["errorCode"])
task_id = resp["taskId"]
# 2. Poll until ready
while True:
time.sleep(5)
result = requests.post(f"{BASE}/getTaskResult", json={
"clientKey": API_KEY,
"taskId": task_id,
}).json()
if result["errorId"] != 0:
raise RuntimeError(result["errorCode"])
if result["status"] == "ready":
print(result["solution"]["gRecaptchaResponse"])
break
const BASE = "https://api.captcha-solver.com";
const API_KEY = "YOUR_API_KEY";
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
async function solve() {
// 1. Create a task
const create = await fetch(`${BASE}/createTask`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
clientKey: API_KEY,
task: {
type: "RecaptchaV2TaskProxyless",
websiteURL: "https://example.com/login",
websiteKey: "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
},
}),
}).then((r) => r.json());
if (create.errorId !== 0) throw new Error(create.errorCode);
// 2. Poll until ready
while (true) {
await sleep(5000);
const result = await fetch(`${BASE}/getTaskResult`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ clientKey: API_KEY, taskId: create.taskId }),
}).then((r) => r.json());
if (result.errorId !== 0) throw new Error(result.errorCode);
if (result.status === "ready") return result.solution.gRecaptchaResponse;
}
}
solve().then(console.log);
reCAPTCHA v3
# 1. Create a task
curl -s -X POST https://api.captcha-solver.com/createTask \
-H "Content-Type: application/json" \
-d '{
"clientKey": "YOUR_API_KEY",
"task": {
"type": "RecaptchaV3TaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"minScore": 0.3,
"pageAction": "login"
}
}'
# -> {"errorId":0,"taskId":100}
# 2. Poll for the result (repeat every ~5s until status is "ready")
curl -s -X POST https://api.captcha-solver.com/getTaskResult \
-H "Content-Type: application/json" \
-d '{"clientKey":"YOUR_API_KEY","taskId":100}'
# -> {"errorId":0,"status":"processing"}
# -> {"errorId":0,"status":"ready","solution":{"gRecaptchaResponse":"03AGdBq..."}}
import time
import requests
BASE = "https://api.captcha-solver.com"
API_KEY = "YOUR_API_KEY"
# 1. Create a task
resp = requests.post(f"{BASE}/createTask", json={
"clientKey": API_KEY,
"task": {
"type": "RecaptchaV3TaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"minScore": 0.3,
"pageAction": "login",
},
}).json()
if resp["errorId"] != 0:
raise RuntimeError(resp["errorCode"])
task_id = resp["taskId"]
# 2. Poll until ready
while True:
time.sleep(5)
result = requests.post(f"{BASE}/getTaskResult", json={
"clientKey": API_KEY,
"taskId": task_id,
}).json()
if result["errorId"] != 0:
raise RuntimeError(result["errorCode"])
if result["status"] == "ready":
print(result["solution"]["gRecaptchaResponse"])
break
const BASE = "https://api.captcha-solver.com";
const API_KEY = "YOUR_API_KEY";
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
async function solve() {
// 1. Create a task
const create = await fetch(`${BASE}/createTask`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
clientKey: API_KEY,
task: {
type: "RecaptchaV3TaskProxyless",
websiteURL: "https://example.com/login",
websiteKey: "6Le-xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
minScore: 0.3,
pageAction: "login",
},
}),
}).then((r) => r.json());
if (create.errorId !== 0) throw new Error(create.errorCode);
// 2. Poll until ready
while (true) {
await sleep(5000);
const result = await fetch(`${BASE}/getTaskResult`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ clientKey: API_KEY, taskId: create.taskId }),
}).then((r) => r.json());
if (result.errorId !== 0) throw new Error(result.errorCode);
if (result.status === "ready") return result.solution.gRecaptchaResponse;
}
}
solve().then(console.log);
Cloudflare Turnstile
# 1. Create a task
curl -s -X POST https://api.captcha-solver.com/createTask \
-H "Content-Type: application/json" \
-d '{
"clientKey": "YOUR_API_KEY",
"task": {
"type": "TurnstileTaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "0x4AAAAAAAxxxxxxxxxxxxxxxx"
}
}'
# -> {"errorId":0,"taskId":100}
# 2. Poll for the result (repeat every ~5s until status is "ready")
curl -s -X POST https://api.captcha-solver.com/getTaskResult \
-H "Content-Type: application/json" \
-d '{"clientKey":"YOUR_API_KEY","taskId":100}'
# -> {"errorId":0,"status":"processing"}
# -> {"errorId":0,"status":"ready","solution":{"token":"0.zxcv..."}}
import time
import requests
BASE = "https://api.captcha-solver.com"
API_KEY = "YOUR_API_KEY"
# 1. Create a task
resp = requests.post(f"{BASE}/createTask", json={
"clientKey": API_KEY,
"task": {
"type": "TurnstileTaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "0x4AAAAAAAxxxxxxxxxxxxxxxx",
},
}).json()
if resp["errorId"] != 0:
raise RuntimeError(resp["errorCode"])
task_id = resp["taskId"]
# 2. Poll until ready
while True:
time.sleep(5)
result = requests.post(f"{BASE}/getTaskResult", json={
"clientKey": API_KEY,
"taskId": task_id,
}).json()
if result["errorId"] != 0:
raise RuntimeError(result["errorCode"])
if result["status"] == "ready":
print(result["solution"]["token"])
break
const BASE = "https://api.captcha-solver.com";
const API_KEY = "YOUR_API_KEY";
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
async function solve() {
// 1. Create a task
const create = await fetch(`${BASE}/createTask`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
clientKey: API_KEY,
task: {
type: "TurnstileTaskProxyless",
websiteURL: "https://example.com/login",
websiteKey: "0x4AAAAAAAxxxxxxxxxxxxxxxx",
},
}),
}).then((r) => r.json());
if (create.errorId !== 0) throw new Error(create.errorCode);
// 2. Poll until ready
while (true) {
await sleep(5000);
const result = await fetch(`${BASE}/getTaskResult`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ clientKey: API_KEY, taskId: create.taskId }),
}).then((r) => r.json());
if (result.errorId !== 0) throw new Error(result.errorCode);
if (result.status === "ready") return result.solution.token;
}
}
solve().then(console.log);
Postman
In Postman: create a POST request to the endpoint, set the body to raw JSON, and paste the request body below. Or import the ready collection (Import > Raw text):
{
"info": {
"name": "captcha-solver",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "createTask",
"item": [
{
"name": "reCAPTCHA v2 (proxyless)",
"request": {
"method": "POST",
"header": [{ "key": "Content-Type", "value": "application/json" }],
"url": "https://api.captcha-solver.com/createTask",
"body": {
"mode": "raw",
"raw": "{\n \"clientKey\": \"YOUR_API_KEY\",\n \"task\": {\n \"type\": \"RecaptchaV2TaskProxyless\",\n \"websiteURL\": \"https://example.com/login\",\n \"websiteKey\": \"6Le-xxxx\"\n }\n}"
}
}
},
{
"name": "reCAPTCHA v2 (your proxy)",
"request": {
"method": "POST",
"header": [{ "key": "Content-Type", "value": "application/json" }],
"url": "https://api.captcha-solver.com/createTask",
"body": {
"mode": "raw",
"raw": "{\n \"clientKey\": \"YOUR_API_KEY\",\n \"task\": {\n \"type\": \"RecaptchaV2Task\",\n \"websiteURL\": \"https://example.com/login\",\n \"websiteKey\": \"6Le-xxxx\",\n \"proxyType\": \"http\",\n \"proxyAddress\": \"1.2.3.4\",\n \"proxyPort\": 8080,\n \"proxyLogin\": \"user\",\n \"proxyPassword\": \"password\"\n }\n}"
}
}
},
{
"name": "reCAPTCHA v3 (proxyless)",
"request": {
"method": "POST",
"header": [{ "key": "Content-Type", "value": "application/json" }],
"url": "https://api.captcha-solver.com/createTask",
"body": {
"mode": "raw",
"raw": "{\n \"clientKey\": \"YOUR_API_KEY\",\n \"task\": {\n \"type\": \"RecaptchaV3TaskProxyless\",\n \"websiteURL\": \"https://example.com/login\",\n \"websiteKey\": \"6Le-xxxx\",\n \"minScore\": 0.3,\n \"pageAction\": \"login\"\n }\n}"
}
}
},
{
"name": "Turnstile (proxyless)",
"request": {
"method": "POST",
"header": [{ "key": "Content-Type", "value": "application/json" }],
"url": "https://api.captcha-solver.com/createTask",
"body": {
"mode": "raw",
"raw": "{\n \"clientKey\": \"YOUR_API_KEY\",\n \"task\": {\n \"type\": \"TurnstileTaskProxyless\",\n \"websiteURL\": \"https://example.com/login\",\n \"websiteKey\": \"0x4AAAAAAAxxxx\"\n }\n}"
}
}
},
{
"name": "Turnstile (your proxy)",
"request": {
"method": "POST",
"header": [{ "key": "Content-Type", "value": "application/json" }],
"url": "https://api.captcha-solver.com/createTask",
"body": {
"mode": "raw",
"raw": "{\n \"clientKey\": \"YOUR_API_KEY\",\n \"task\": {\n \"type\": \"TurnstileTask\",\n \"websiteURL\": \"https://example.com/login\",\n \"websiteKey\": \"0x4AAAAAAAxxxx\",\n \"proxyType\": \"http\",\n \"proxyAddress\": \"1.2.3.4\",\n \"proxyPort\": 8080\n }\n}"
}
}
}
]
},
{
"name": "getTaskResult",
"request": {
"method": "POST",
"header": [{ "key": "Content-Type", "value": "application/json" }],
"url": "https://api.captcha-solver.com/getTaskResult",
"body": {
"mode": "raw",
"raw": "{\n \"clientKey\": \"YOUR_API_KEY\",\n \"taskId\": 100\n}"
}
}
},
{
"name": "getBalance",
"request": {
"method": "POST",
"header": [{ "key": "Content-Type", "value": "application/json" }],
"url": "https://api.captcha-solver.com/getBalance",
"body": {
"mode": "raw",
"raw": "{\n \"clientKey\": \"YOUR_API_KEY\"\n}"
}
}
}
]
}
Vibe coding: llms.txt
Building the integration with ChatGPT, Claude or a coding agent? Just drop it the link below. Inside is the whole API in one plain-text file: endpoints, request examples, fields for every captcha type, polling logic and error codes. Your AI writes the integration code without ever opening these pages.
Ready-to-paste promptRead https://captcha-solver.com/llms.txt and write a Python function solve_recaptcha(website_url, website_key) that solves reCAPTCHA v2 through this API. Take the API key from the CAPTCHA_API_KEY environment variable.
Errors
Errors are returned with HTTP 200 and a JSON body: "errorId" is non-zero, together with "errorCode" and "errorDescription". Client libraries match on errorId / errorCode.
| Code | Meaning |
|---|---|
ERROR_KEY_DOES_NOT_EXIST | Invalid or missing clientKey |
ERROR_ZERO_BALANCE | Not enough balance to create the task |
ERROR_NO_SUCH_CAPCHA_ID | Unknown taskId or the task has expired |
ERROR_CAPTCHA_UNSOLVABLE | The captcha could not be solved (funds refunded) |
ERROR_TASK_ABSENT | The task object is missing |
ERROR_TASK_NOT_SUPPORTED | Task type is not supported |
Need help? Contact support.